About Question enthuware.ocpjp.v17.2.3741 :

Help and support on OCA OCP Java Programmer Certification Questions
1Z0-808, 1Z0-809, 1Z0-815, 1Z0-816, 1Z0-817

Moderator: admin

Post Reply
jerry___
Posts: 9
Joined: Tue Nov 26, 2024 2:08 pm
Contact:

About Question enthuware.ocpjp.v17.2.3741 :

Post by jerry___ »

Hi Enthuware,

The explanation of this question says:
The order of the numbers or the actual numbers that are printed cannot be determined. There are 10 threads that will be executing the run() method and any thread may run at any time. Therefore, it is possible that a thread may increment threadcounter (say, from 1 to 2) and before it gets a chance to print the value, it is swapped out and another thread starts executing the method (thereby, incrementing threadcounter from 2 to 3, and printing 3). Now, if the earlier thread executes, it will print 3. Thus, 3 will be printed twice and 2 will never be printed.
This seems absolutely spot on. So there are two issues, the uniqueness of the results and the ordering of the results. Next part:
Further, since the threadcounter is not declared as volatile, the updates made by one thread may not be visible to another thread. It is, therefore, possible that each of the ten threads see its value as 0 and update it to 1. Thus, one possible outcome could be that 1 is printed 10 times!
This suggests that adding the keyword volatile to the threadcounter, that would fix the problem of uniqueness.

I added a little sleep() within run() method to test this, I hope this is a representative test. Without this, I always got unique and perfectly ordered results just because of chance, I guess.

Code: Select all

                try
                {
                        this.sleep(1000);
                } catch (InterruptedException e) {
                        e.printStackTrace();
                }
With this addition, I performed each test a couple of times in order to reduce the risks of false positives/ false negatives.

I still got the same numbers more than once after making the int volatile and also the ordering wasn't incremental. The suggested solution proved not to be a real solution to any of both issues, assuming my sleep() addition didn't trouble the results.

I guess that's because volatile prevents order-of-operation optimization within the processor or at JRE level but it doesn't merge "retrieving", "updating" and then "retrieving again" to one single operation. They're still separate things. I might very well be wrong in this but right now, it makes sense to me.

Next part:
To fix the problem, you can make the run method synchronized so that only one thread will try to update threadcounter at a time. Another thread will get a chance only after one thread exits out of the run method.
So additionally to my this.sleep() method and the volatile keyword, I made the run method synchronized by adding that keyword to the method.

It doesn't seem to help much in either the fact that results are still not unique after this and also they still come in an undeterministic order.
I think it has to do with the fact that the monitor is then on the instance of my class while the threadcounter is a static variable.

If I remove the synchronized keyword from the run() method, and instead, add synchronized(TestClass.class), that does solve both the problems of uniqueness of the results and ordering of the results. I also actually have to wait a second for each result to show up with this modification. It makes sense to me, the monitor is now static so whichever instance there is, has to consider that monitor.

The final part of the explanation:
You may also use AtomicInteger instead of int and use its getAndIncrement method instead of the post increment operator.
The AtomicInteger solution by itself seems to only fix the issue of uniqueness, not the ordering of the results. This makes sense to me.


I think I learned a lot by this question, the explanation and testing things out. I'd be happy to hear if I made any wrong assumptions or if there's anything more to take from this.

admin
Site Admin
Posts: 10383
Joined: Fri Sep 10, 2010 9:26 pm
Contact:

Re: About Question enthuware.ocpjp.v17.2.3741 :

Post by admin »

You have understood correctly. The statement in the explanation is not right. It should be:
"To fix the problem, you can put the code in the run method within a synchronized block that synchronizes on a common object so that only one thread will try to update threadcounter at a time. Another thread will get a chance only after one thread exits out of the run method."

AtomicInteger will fix the issue of missing updates but it will not ensure ordering.

sarausa
Posts: 1
Joined: Tue Mar 25, 2025 8:37 pm
Contact:

Re: About Question enthuware.ocpjp.v17.2.3741 :

Post by sarausa »

admin wrote:
Fri Jan 17, 2025 6:51 am
You have understood correctly. The statement in the explanation is not right. It should be:
"To fix the problem, you can put the code in the run method within a synchronized block that synchronizes on a common object so that only one thread will try to update threadcounter at a time. Another thread will get a chance only after one thread exits out of the run method." Suika game

AtomicInteger will fix the issue of missing updates but it will not ensure ordering.
As you pointed out, AtomicInteger does not guarantee the order of operations. This means that if you need to ensure that counter update operations are performed in a particular order, AtomicInteger will not satisfy this requirement.

Post Reply

Who is online

Users browsing this forum: Bing [Bot] and 10 guests