多執行緒 同步函式

2021-07-02 01:50:42 字數 3023 閱讀 7888

來看下面這個程式

/*需求:

銀行有一金庫。有兩個儲戶分別存300元,每次存100,存3次。

目的:該程式是否有安全問題。如果有,如何解決?

*/

class bank

}class cus implements runnable }}

class bankdemo

}

執行結果可能為:

如何找問題:

1.明確哪些**是多執行緒執行**

2.明確共享資料

3.明確多執行緒執行**中哪些語句是操作共享資料的

在上面的執行程式中,

run方法和add方法是多執行緒執行**

b和sum是共享資料

操作b的是b.add(100); 操作sum的是sum = sum + n;和system.out.println("sum = "+sum);

先用同步**塊封裝**

class bank

catch(exception e){}

system.out.println("sum = "+sum);

} }}class cus implements runnable }}

class bankdemo

}

函式和同步**塊都可以封裝**,唯一的區別是同步**塊具備同步的特性。

為了讓函式具備同步性。把

synchronized關鍵字作為修飾符放到函式上

class test implements runnable

catch(exception e){}

system.out.println(thread.currentthread().getname()+" tick = "+tick--);

}//}

} }}class ticketdemo

}

執行結果:

可以看到程式中只有thread-0執行了。這是因為當乙個執行緒搶到執行權進入run方法後,就把狀態改為已鎖狀態,其他執行緒無法進入。

解決方法:將需要同步的**封裝成函式

class test implements runnable

} public synchronized void show()

catch(exception e){}

system.out.println(thread.currentthread().getname()+" tick = "+tick--);

} }}class ticketdemo

}

同步函式用的是哪乙個鎖呢?

函式需要被物件呼叫。那麼函式都有乙個所屬物件引用,就是this。

所以同步函式的鎖是this

通過買票程式來驗證

使用兩個執行緒來買票,乙個執行緒在同步**塊中,乙個執行緒在同步函式中,都在執行買票動作。若同步不會出現錯誤的票。

class test implements runnable

catch(exception e){}

system.out.println(thread.currentthread().getname()+" tick = "+tick--);}}

}} else

while(true)

show();

} public synchronized void show()

catch(exception e){}

system.out.println(thread.currentthread().getname()+" show... "+tick--);

} }}class ticketdemo1

catch(exception e){}

t.flag = false;

t2.start();}}

輸出結果中有-1號票,說明這個程式是不安全的。

已經使用了同步還出現錯誤。這時要考慮同步的兩個前提條件:

1.必須有兩個或兩個以上的執行緒

2.必須使用同一把鎖。

通過分析,同步**塊中的鎖是obj,而同步函式中的鎖不是。把鎖都換成this

class test implements runnable

catch(exception e){}

system.out.println(thread.currentthread().getname()+" tick = "+tick--);}}

}} else

while(true)

show();

} public synchronized void show()

catch(exception e){}

system.out.println(thread.currentthread().getname()+" show... "+tick--);

} }}class ticketdemo1

catch(exception e){}

t.flag = false;

t2.start();}}

輸出結果正確,說明同步函式的鎖是this。

如果同步函式被靜態修飾後,使用的鎖是什麼?

通過驗證,發現不再是this

,因為靜態方法中不可以定義

this。

靜態進記憶體時,記憶體中沒有本類物件,但是一定有該類對應的位元組碼檔案物件 類名.class  

該物件的型別是

class

靜態的同步方法使用的鎖是該方法所在類的位元組碼檔案  類名.class.

多執行緒靜態同步函式

多執行緒靜態同步函式和非靜態同步函式的區別是啥?靜態同步函式 就是方法使用了static關鍵字修飾 非靜態同步函式 沒有用static關鍵字修飾的方法,也就是使用this鎖的同步函式 那麼靜態同步函式使用的啥鎖呢?分析 兩個執行緒,乙個執行緒使用靜態同步函式,乙個使用同步 塊this鎖,如果執行緒不...

多執行緒同步

synchronized 物件 其中物件相當於乙個標誌 鎖 用於判斷 同步 塊 同步的前提必須是兩個或兩個以上的執行緒,且共用同乙個鎖 同步解決了多執行緒的安全問題 弊端 多執行緒需要判斷鎖,消耗了資源 同步函式 將synchronized放在函式名前面即可 即具有同步性質 使用的鎖是this 靜態...

多執行緒同步

同步 即限制某個資源在同一時間只能被同乙個執行緒訪問。執行緒安全問題 多個執行緒共同處理共享資源所導致的。解決 多執行緒處理乙個共享資源時,將處理共享資源的 利用關鍵字synchronized修飾。同步 塊 synchronized修飾 塊,synchronized lock 同步方法 synchr...