public class SyncBlockIssue {
public static void main(String[] args) {
Thread r1= new Multi();
Thread t1= new Thread(r1);
Thread t2= new Thread(r1);
t1.start();
t2.start();
}
}
class Multi extends Thread
{
Integer count =new Integer(0);
@Override
public void run() {
for(int i=0;i<100000;i )
{
synchronized (count) {
//synchronized (this) { //working fine with this
count ;
}
}
System.out.println(Thread.currentThread().getName() " " count);
}
}
上面的代碼從第二個執行緒列印 200 萬個,無論我在獲取“this”鎖時運行多少次,但是在任意列印時,當獲取鎖“計數”物件時。有人可以解釋一下區別嗎。
uj5u.com熱心網友回復:
這是我的猜測,因為我無法使用注釋輸入這么多單詞。
Integer 物件是不可變的:
/**
* The value of the {@code Integer}.
*
* @serial
*/
private final int value;
/**
* Constructs a newly allocated {@code Integer} object that
* represents the specified {@code int} value.
*
* @param value the value to be represented by the
* {@code Integer} object.
*/
public Integer(int value) {
this.value = value;
}
因此,當您這樣做時count ,Integer將創建一個新物件。count然后將參考定向到新物件。
假設以下流程:
Thread r1獲取count鎖(注意是count object被鎖的),此時thread r2被阻塞。r1呼叫count,Integer創建一個新物件。count然后將參考定向到新物件。并r1釋放鎖。(這個鎖指的是之前的Integer物件)。r2被阻塞的獲取鎖。r1也獲得了鎖,因為count已經指向了一個新物件。兩個執行緒都執行
count:出現問題。
以下代碼證明兩個執行緒同時持有“鎖”
for(int i=0; i<2; i )
{
synchronized (count) {
System.out.println(Thread.currentThread().getName() "get lock");
count ;
if (i == 1) {
try {
Thread.sleep(100000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() "release lock");
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/316284.html
上一篇:變數應該如何傳遞給方法之外的人
