Reputation: 11131
Playing with synchronization, I basically have two cuncurrent threads executing a method of the same object, but probably I'm getting something wrong.
Given this piece of code
public class Test {
public static void main(String... args) throws InterruptedException{
new Test();
}
Test() throws InterruptedException{
Stuff s = new Stuff();
Th t1 = new Th(1,s);
Th t2 = new Th(2,s);
t1.start();
Thread.sleep(1000);
t2.start();
}
}
class Stuff{
public Integer count=0;
void doStuff(int threadId){
System.out.println(threadId + ": in doStuff");
synchronized (count) {
count += 100;
if (threadId == 1) {
try {Thread.sleep(3000);}
catch (InterruptedException e) {e.printStackTrace();}
}
System.out.println(threadId + ": count = " + count);
}
}
}
class Th extends Thread{
public Stuff s;
public int id;
@Override
public void run(){
System.out.println(id+": thread run");
s.doStuff(id);
}
Th(int id_,Stuff s_){
s=s_;
id=id_;
System.out.println(id+": thread created");
}
}
I get this output
1: thread created 2: thread created 1: thread run 1: in doStuff 2: thread run 2: in doStuff 2: count = 200 1: count = 200
Why is t1
printing "200"?
Shouldn't t2
wait for t1
to execute the synchronized block before being able to get the lock on count
and then execute the block?
Upvotes: 3
Views: 90
Reputation: 262494
synchronized (count) {
count += 100;
That does not work.
You are synchronizing on Objects, not on variables or fields.
Every time you increase the count
, that field will point at a different Integer
object. So your synchronized block uses a different monitor all the time.
You need to find a "stable" lock object, for example
private final Object lockMonitor = new Object();
(then you can say synchronized (lockMonitor){}
instead)
Upvotes: 10