Why is this sync example not working?
Playing with sync, I basically have two cuncurrent threads executing a method of the same object, but I'm probably 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 am getting 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 t1
does "200" print? Shouldn't you t2
wait t1
for a synchronized block to execute before being able to acquire a lock on count
and then execute the block?
source to share
synchronized (count) {
count += 100;
This does not work.
You are syncing objects, not variables or fields.
Each time you zoom in count
, this field points to a different object Integer
. This way your synced block is using different monitors all the time.
You need to find a "stable" lock object like
private final Object lockMonitor = new Object();
(then you can tell synchronized (lockMonitor){}
)
source to share