Shouldnt a lock on class block threads from all class instances
public class Fern extends Thread
{
private String x = "varun";
public void run()
{
synchronized(Fern.class){
System.out.println(x);
try {
sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
x = "Anku";
}
}
pu开发者_高级运维blic static void main(String args[]) throws Exception
{
Fern f = new Fern();
Thread t1 = new Thread(new Fern());
Thread t2 = new Thread(new Fern());
t1.start();
t2.start();
}
}
Output is: varun varun
Since the block has been synchronized on Fern.class, only one thread should be allowed to enter the block at a time irrespective of which instance it belongs to since there is only one lock for the class for all instances. If I replace new Fern() in the Thread constructor with a single Fern object, the output is: varun Anku. The behaviour is what would have been had I synchronized on(this). I dont understand why this is happening since I synchronized
x
is not a static
variable. Change it to static
.
static String x = "varun";
EDIT:
or pass the same object as parameter to t1
and t2
.
Fern f = new Fern();
Thread t1 = new Thread(f); // pass the same object
Thread t2 = new Thread(f);
x
is an instance variable - in other words, even though only one thread can enter that block at a time, they're looking at different variables. Changing the value of x
in the first thread doesn't affect the x
that the second thread is looking at.
In other words, the synchronization is "correct" (if you don't want more than one thread to enter that block regardless of instance) but your data access isn't doing what you think it should.
As a side note, I personally prefer locking on references which only my class can see.
As another side note, it would be better if Fern
implemented Runnable
rather than extending Thread
- you're currently passing one thread to another one's constructor, which doesn't make much sense...
The x
in each instance of the thread is a different one. Try private static String x
to use a shared x
in both cases.
This has nothing to do with synchronization. x
is an instance variable, so each Fern
instance has its own copy, initialized to "varun", then printed, then set to "Anku".
Because you have two different Fern
instances, the fact that one of them changes the value of its x
field is not seen by the other. (I am guessing, since you don't give the declaration of x
. To get better answers, post only complete code.)
精彩评论