why its not printing Numbers 1 to 5 in sequence with "N Done" anywhere in the sequence where N cannot be determined??? what i understand is, whenever run method called it will increment into "threadcounter" variable and print on console.
dude you are creating a new object everytime in the loop.. five times
scjp 1.6 91%, preparing for scmad
"Time to get MAD now.. we will get even later"....by someone unknown
Neha Daga
Ranch Hand
Joined: Oct 30, 2009
Posts: 504
posted
0
yes, Raju is right.
you are creating a new thread object everytime the for loop runs and start it. but its jvm dependent that which thread will get into running state so whichever thread gets control first sequence depends on that, even if your run method is synchronized.
Minhaj kaimkhani wrote:why its not printing Numbers 1 to 5 in sequence with "N Done" anywhere in the sequence where N cannot be determined?
Is that not what it's doing? If not, what *are* you getting?
the order of 1 - 5 is not in sequence
Ulf Dittmer
Marshal
Joined: Mar 22, 2005
Posts: 35232
7
posted
0
A synchronized method (like the run method in your code) locks on its object - in effect, the "this" object. Since all 5 run method invocations occur in different objects, no synchronization between them happens. If you synchronize all 5 threads on the same object, then you'll get the result you expected. Something like this:
Lotary Li
Greenhorn
Joined: Dec 21, 2009
Posts: 5
posted
0
Another way for it. *note* using Runnable interface.
Yes guys you fixed the problem assuming that desired behaviour of the program is that it should produce distinct numbers in correct order. It's worth mentioning that the original program's output is not fully predictable, but we can say that it will print numbers where each number will be equal or greater than the former one. E.g. it could produce something like:
1
3
3
4
5
5 DONE
It's because threads are not synchronized with each other (as written above), and they may be switched between line 9 and 10.
Neha Daga
Ranch Hand
Joined: Oct 30, 2009
Posts: 504
posted
0
You dont need to implement the Runnable interface. The code can remain exactly as it is, just replace -
with
and it will still work.
I guess the reason being the same run method is called (so synchronization works) instead of new threads being created with every for iteration.
you are creating a new thread object everytime the for loop runs and start it. but its jvm dependent that which thread will get into running state so whichever thread gets control first sequence depends on that, even if your run method is synchronized.
Neha And Raju am not getting your point!! yes we are creating new object into loop every time, but the counter variable is static so it must be shared among all the objects
to make sure the correct sequence of output we can call join method like as well:
Ulf Dittmer
Marshal
Joined: Mar 22, 2005
Posts: 35232
7
posted
0
yes we are creating new object into loop every time, but the counter variable is static so it must be shared among all the objects
It's not about the counter variable, it's about the fact that *no* synchronization is happening, because each thread synchronizes on a different lock object. Synchronization only happens between threads that synchronize on the *same* lock object.
That means that "threadcounter++" and "System.out.println(threadcounter)" are *not* executed atomically, and that there can be a switch from one thread to another before the println statement.
...even we have threadcounter shared variable for all objects.
Ulf Dittmer
Marshal
Joined: Mar 22, 2005
Posts: 35232
7
posted
0
The code you just added does nothing at all, since the main method is single-threaded. The problem is not about synchronization in the main method, it's about synchronization in the run method.
Let's look at it the other way around: *If* you were to accept that synchronization is *not* happening, would you understand why you're getting the output that you're getting? If not, I suggest you work through the Sun Java Tutorial chapter on concurrency: http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html
Ulf Dittmer wrote:The code you just added does nothing at all, since the main method is single-threaded. The problem is not about synchronization in the main method, it's about synchronization in the run method.
Let's look at it the other way around: *If* you were to accept that synchronization is *not* happening, would you understand why you're getting the output that you're getting? If not, I suggest you work through the Sun Java Tutorial chapter on concurrency: http://java.sun.com/docs/books/tutorial/essential/concurrency/index.html
Yes I do understand, while a thread has incremented the threadcounter and is about to print it, another thread may increment the value.
-Minhaj
Neha Daga
Ranch Hand
Joined: Oct 30, 2009
Posts: 504
posted
0
ok..let me try to explain.
everytime when you create a new TestClass object in the for loop you start a new thread and each new thread has its own run method, so when each thread runs it will execute its run method and access threadcounter which is a class variable so when one thread is about to print threadcounter some other thread may have enter its run method and and changed the threadcounter it simply depends on which thread gets into running state when and synchronising run method here will not do any synchronization.
now if you look at Ulf's code he has synchronized the block of statements which include threadcounter increment and its printing out making it whole as an atomic operation so no matter which threads come into running state when this block will be accessed by only one thread and now synchronization is perfect.
and if you look at my or Lotary's code we are passing a TestClass object to every thread being created in the for loop, Now every thread will execute the same run method which is of TestClass object passed to that thread so here synchronized run method will meet your goal.
everytime when you create a new TestClass object in the for loop you start a new thread and each new thread has its own run method, so when each thread runs it will execute its run method and access threadcounter which is a class variable so when one thread is about to print threadcounter some other thread may have enter its run method and and changed the threadcounter it simply depends on which thread gets into running state when and synchronising run method here will not do any synchronization.
Yes, this is what i have said in my last post.
Neha Daga wrote:now if you look at Ulf's code he has synchronized the block of statements which include threadcounter increment and its printing out making it whole as an atomic operation so no matter which threads come into running state when this block will be accessed by only one thread and now synchronization is perfect.
So, you mean that only 1 thread will execute at a time(this means valid synchronization too??) so out put should be sequence numbers?? if only one thread run at a time so the chances to increment of threadcounter obviously 1 at a time!
please dont mind if i understand you wrong, please clear.
Minhaj, please don't put your own statements in quote tags, it gets confusing that way (even if you use colors etc). I've fixed it for you.
Minhaj kaimkhani wrote:So, you mean that only 1 thread will execute at a time(this means valid synchronization too??)
The whole point of synchronization is to allow only one thread to execute a piece of code to prevent concurrency issues. Look at the following code
Here we are synchronizing on TestClass.class object which will be shared between all instances of TestClass (this is just a modified version of Ulf's code).
Minhaj kaimkhani wrote:if only one thread run at a time so the chances to increment of threadcounter obviously 1 at a time!
Yes this is right. Since only 1 thread gets a chance to increment and display the value of threadcounter at a time, the output would be in sequence...