是這樣的,我想知道synchronized(obj)的用法,然後寫了如下的代碼,運行結果我如何都搞不清,還請各位指點。
代碼1:
public class MyObj
{
private Integer a;
private Double b;
private Integer c;
public void setA()
{
System.out.println(Thread.currentThread().getName() + "搶到鎖..setA");
synchronized(c)
{
System.out.println(" " + Thread.currentThread().getName() + " " + this.a + " " + this.b);
this.a = 1;
this.b = 2.0;
try{
Thread.sleep(200);//(int) (Math.random()*2000)
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(" " + Thread.currentThread().getName() + " " + this.a + " " + this.b);
}
}
public void setB()
{
System.out.println(Thread.currentThread().getName() + "搶到鎖....setB");
synchronized(c)
{
System.out.println(" " + Thread.currentThread().getName() + " " + this.a + " " + this.b);
this.a = 3;
this.b = 4.0;
try{
Thread.sleep(200);//(int) (Math.random()*2000)
}catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println(" " + Thread.currentThread().getName() + " " + this.a + " " + this.b);
}
}
public MyObj()
{
this.a = -1;
this.b = -1.0;
this.c = 0;
}
}
代碼2:
public class Change
{
private MyObj myObj;
public Change(MyObj myObj)
{
this.myObj = myObj;
}
public static void main(String args[])
{
final MyObj myObj = new MyObj();
final Integer a = 1;
Thread thread1 = new Thread(new Runnable(){
public void run()
{
for(int product = 1; product <= 3; ++product)
{
try{
Thread.sleep((int) (Math.random()*200));//(int) (Math.random()*2000)
myObj.setA();
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
},"thread1");
Thread thread2 = new Thread(new Runnable(){
public void run()
{
for(int product = 1; product <= 3; ++product)
{
try{
Thread.sleep((int) (Math.random()*200));//(int) (Math.random()*2000)
myObj.setB();
}catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
},"thread2");
thread1.start();
thread2.start();
}
}
輸出結果(之一):
thread2搶到鎖....setB
thread2 -1 -1.0
thread1搶到鎖..setA
thread2 3 4.0
thread1 3 4.0
thread2搶到鎖....setB
thread1 1 2.0
thread2 1 2.0
thread1搶到鎖..setA
thread2 3 4.0
thread1 3 4.0
thread2搶到鎖....setB
thread1 1 2.0
thread2 1 2.0
thread1搶到鎖..setA
thread2 3 4.0
thread1 3 4.0
thread1 1 2.0
** 但是**,如果將
System.out.println(Thread.currentThread().getName() + "搶到鎖....setA");
和
System.out.println(Thread.currentThread().getName() + "搶到鎖....setB");
放到 synchronized(c) 塊裡面,那麼結果之一:
thread1搶到鎖..setA
thread1 -1 -1.0
thread1 1 2.0
thread2搶到鎖....setB
thread2 1 2.0
thread2 3 4.0
thread1搶到鎖..setA
thread1 3 4.0
thread1 1 2.0
thread2搶到鎖....setB
thread2 1 2.0
thread2 3 4.0
thread1搶到鎖..setA
thread1 3 4.0
thread1 1 2.0
thread2搶到鎖....setB
thread2 1 2.0
thread2 3 4.0
可能 輸出有先後,但是 至少 thread1,thread2的輸出之間,不會相互干擾。。。
我仔細觀察了,上面的結果,雖然相互干擾,但是也不會出錯,但是為什麼 會這樣呢? 既然 已經進入 thread1了,thread2怎麼還能得到鎖呢。。如果這樣的話,synchronized(obj)還有啥意思啊(obj不一定是this)? 。實在沒搞懂啊。再次麻煩各位幫忙。
總共就1個幣,諒解哈。
還是強調下面這種寫法,在打印“搶到鎖”時,實際不一定搶到鎖了,因為日志是在synchronized前面打印的,只有在內部打印才是確實搶到鎖~:
public void setB()
{
System.out.println(Thread.currentThread().getName() + "搶到鎖....setB");
synchronized(c)
{
這樣是不是容易理解點:
thread2搶到鎖....setB ----進入thread2,明確這裡不是同步塊,不受synchronized影響
thread2 -1 -1.0 -----thread2獲得鎖,這是同步塊裡面第一句日志,確定是獲取到鎖了
thread1搶到鎖..setA -----進入thread1
thread2 3 4.0 -----thread2釋放鎖,這是同步塊最後一句日志,打完就可以認為是釋放鎖了
thread1 3 4.0 -----thread1獲得鎖
thread2搶到鎖....setB -----進入thread2
thread1 1 2.0 -----thread1釋放鎖
thread2 1 2.0
thread1搶到鎖..setA
thread2 3 4.0
thread1 3 4.0
thread2搶到鎖....setB
thread1 1 2.0
thread2 1 2.0
thread1搶到鎖..setA
thread2 3 4.0
thread1 3 4.0
thread1 1 2.0