akila sekaran
Ranch Hand
Posts: 48
Write a class Num, that holds an integer, that starts at 0. It has two functions, inc() and dec(). the internal integer may not go below 0, or above 10. inc() will increase the integer by one, and if it is unable, it will block, and continue when it can. dec() will decrement the integer by one, and if it unable, it will block, and continue when it can.
Create 100 threads, that each do the following:
adds one to the integer, waits for a second, removes one from the integer, waits for a second, in an infinite loop.

I get the following as a result in infinite loop.

Where do you think the code has mistake?

Steve Luke
Bartender
Posts: 4181
22
Where do you think the code has mistake?

What makes you think the code has a mistake? What do you expect to happen and what is the difference between that and what is happening?

akila sekaran
Ranch Hand
Posts: 48
Steve Luke wrote:
Where do you think the code has mistake?

What makes you think the code has a mistake? What do you expect to happen and what is the difference between that and what is happening?

what i expect is , the inc() method should print till the value reaches 10 and dec() should print till the value reaches 0.

Steve Luke
Bartender
Posts: 4181
22
akila sekaran wrote:what i expect is , the inc() method should print till the value reaches 10 and dec() should print till the value reaches 0.

But for every inc() you have, you have a dec(), so the value should toggle between 4 and 5. So why would you think it should get to 0?

Yes you do have a mistake, but part of the problem is you don't clearly understand the requirements. So I want you to be specific about why you think the output is wrong, at that will lead to the incorrect code

akila sekaran
Ranch Hand
Posts: 48
Steve Luke wrote:
akila sekaran wrote:what i expect is , the inc() method should print till the value reaches 10 and dec() should print till the value reaches 0.

But for every inc() you have, you have a dec(), so the value should toggle between 4 and 5. So why would you think it should get to 0?

Yes you do have a mistake, but part of the problem is you don't clearly understand the requirements. So I want you to be specific about why you think the output is wrong, at that will lead to the incorrect code

ok for the question that i have mentioned above, what do you think should be the correct output. Yes i am a bit confused.

Steve Luke
Bartender
Posts: 4181
22
The correct output for the code is what you posted. Each Exam has a number, and you do an infinite loop where you dec() then inc() that number. If every dec() is followed by exactly one inc() the number will never get below start-1, and never get above start.

So why would you expect that the number would get to zero or ten?

akila sekaran
Ranch Hand
Posts: 48
Steve Luke wrote:The correct output for the code is what you posted. Each Exam has a number, and you do an infinite loop where you dec() then inc() that number. If every dec() is followed by exactly one inc() the number will never get below start-1, and never get above start.

So why would you expect that the number would get to zero or ten?

ACCORDING TO THE QUESTION, the internal integer may not go below 0, or above 10. inc() will increase the integer by one, and if it is unable, it will block, and continue when it can. dec() will decrement the integer by one, and if it unable, it will block, and continue when it can. i have a doubt if my program is able to perform this.

Gaurangkumar Khalasi
Ranch Hand
Posts: 187
akila sekaran wrote:... i have a doubt if my program is able to perform this.

Try out with

akila sekaran
Ranch Hand
Posts: 48
Gaurangkumar Khalasi wrote:
akila sekaran wrote:... i have a doubt if my program is able to perform this.

Try out with

yeah i get it when i use static methods and static "num". What difference does it make ?

Gaurangkumar Khalasi
Ranch Hand
Posts: 187
akila sekaran wrote:yeah i get it when i use static methods and static "num". What difference does it make ?

Static variables and static methods are shared among every objects of the class(in which they are defined). They can be called without creation of the object i.e. with the use of classname.

In the following code snippet, you can see that at each iteration a new object is created and passed it to Thread to run that object's "public void run(){}" method with the use of its variables.
Now, if your variable is not static than each thread will make use of different variable of the particular object, but with the use of static that variable is shared among all objects...

akila sekaran
Ranch Hand
Posts: 48
Gaurangkumar Khalasi wrote:
akila sekaran wrote:yeah i get it when i use static methods and static "num". What difference does it make ?

Static variables and static methods are shared among every objects of the class(in which they are defined). They can be called without creation of the object i.e. with the use of classname.

In the following code snippet, you can see that at each iteration a new object is created and passed it to Thread to run that object's "public void run(){}" method with the use of its variables.
Now, if your variable is not static than each thread will make use of different variable of the particular object, but with the use of static that variable is shared among all objects...

Oh okay got it . So in this case, should i use just static variables or even static methods ?

Gaurangkumar Khalasi
Ranch Hand
Posts: 187
akila sekaran wrote:...Oh okay got it . So in this case, should i use just static variables or even static methods ?

You should use just static variables...

Steve Luke
Bartender
Posts: 4181
22
Unfortunately, just making the number static is not the solution, it will fix the initial problem but will cause blocked threads as no thread will be able to communicate with each other. But it does start to address why you are having the problem. Your initial problem is that each value toggles between 4 and 5, when you expected it to go to zero. This was happening because each thread had its own number it was incrementing. Now you fixed that, so each thread uses the same static number, but what about the Locks and Conditions? Those are still per-instance, which ends up being per-thread in your case, and will cause problem. You could make all those things static, but that isn't very Object Oriented. The correct thing to do is do what the question states:
Write a class Num, that holds an integer, that starts at 0. It has two functions, inc() and dec()

You would create this class, and make one instance of it. Then you can pass that one instance to all the instances of Exam which would do their work on the Num. Since Num has the number, the locks, and the conditions, you would have proper signalling between threads. You would also have properly separated your data (a properly synchronized Num) from the test class (Exam) and looping behavior (the run method). You would also have a class that would work if you later need two different, properly synchronized Num instances.

Gaurangkumar Khalasi
Ranch Hand
Posts: 187
Steve Luke wrote:...each thread uses the same static number, but what about the Locks and Conditions? Those are still per-instance, which ends up being per-thread in your case, and will cause problem...

It is a nice explanation...But Can you elaborate any problem???

Steve Luke
Bartender
Posts: 4181
22
• 1
Gaurangkumar Khalasi wrote:
Steve Luke wrote:...each thread uses the same static number, but what about the Locks and Conditions? Those are still per-instance, which ends up being per-thread in your case, and will cause problem...

It is a nice explanation...But Can you elaborate any problem???

If the number is static then all the instances of Exam will see it and can increment it and decrement it accordingly. But if it reaches 0 then an instance of Exam will go to the lesser.await() method and block. Another Exam will increment above 0 and call lesser.signalAll(). But the second Exam will have a different lesser Object then the one doing lesser.await(), and so the first Exam never wakes up.

Like I said, you could make them all static (the number, the lock, and both conditions) but that leads to problems down the road - it isn't a habit one should get into when there are better alternatives.

Gaurangkumar Khalasi
Ranch Hand
Posts: 187
Steve Luke wrote:If the number is static then all the instances of Exam will see it and can increment it and decrement it accordingly. But if it reaches 0 then an instance of Exam will go to the lesser.await() method and block. Another Exam will increment above 0 and call lesser.signalAll(). But the second Exam will have a different lesser Object then the one doing lesser.await(), and so the first Exam never wakes up.

Thanks