Java同步函數(shù)代碼詳解
更新時間:2017年10月09日 08:35:03 作者:凌風暨
這篇文章主要介紹了Java線程中的同步函數(shù)的相關(guān)內(nèi)容,涉及了實例代碼,需要的朋友,可以參考下。
/*
同步函數(shù)
當函數(shù)中的代碼全部放在了同步代碼塊中,那么這個函數(shù)就是同步函數(shù)
*/
//同步函數(shù)的鎖是this鎖,this是一個引用,this指向的對象就是鎖
//下面證明一下同步函數(shù)的鎖就是this
//創(chuàng)建兩個線程,一個在同步代碼塊中執(zhí)行,另一個在同步函數(shù)中執(zhí)行
//同步代碼塊用的鎖是obj,同步函數(shù)用的所是this
//這就導致了兩個線程存在兩把鎖,會出現(xiàn)上次所說的安全問題,即出現(xiàn)錯誤數(shù)據(jù)
//只有兩個線程同時用一把鎖,才能解決多線程的安全問題
class Ticket implements Runnable{
private int num = 50;//當用靜態(tài)同步函數(shù)時,需要將對象也改為靜態(tài)的
private Object obj = new Object();
//加一個flag標記,一個線程得到CPU,判斷flag值
//如果是true,讓他在同步代碼塊中執(zhí)行,一旦進去就出不來了,因為任務(wù)代碼為死循環(huán)
//否則讓他在同步函數(shù)中執(zhí)行
boolean flag = true;
public void run(){
if(flag){
while(true){
//同步代碼塊,這里用的鎖是obj,與同步函數(shù)用不一樣的鎖,會出現(xiàn)安全問題
//synchronized(obj){
//將鎖改為this,與同步函數(shù)為同一把鎖,就沒有問題了
synchronized(this){//如果下面是靜態(tài)同步函數(shù),則應該把this改為Ticket.class,同一把鎖
if(num>0){
//強制線程放棄CPU,睡眠的線程不會放棄鎖
try{Thread.sleep(20);}catch(InterruptedException e){e.printStackTrace();}
System.out.println(Thread.currentThread().getName()+"...sale..."+num--);//1
}
}//釋放鎖
}
}
else{
while(true){
fun();
}
}
}
////靜態(tài)函數(shù)進內(nèi)存的時候不存在對象,但是存在其所屬類的字節(jié)碼文件對象,屬于Class類型的對象,
//鎖必須是對象,字節(jié)碼文件,也是個對象,所以,靜態(tài)同步函數(shù)的鎖就是其所屬類的字節(jié)碼文件對象
//public static synchronized void fun(){//鎖為Ticket.class
//這個函數(shù)的代碼都是同步代碼塊中的,所以這個函數(shù)可以修飾為同步的,即同步函數(shù)
public synchronized void fun(){
if(num>0){
//強制線程放棄CPU,睡眠的線程不會放棄鎖
try{Thread.sleep(20);}catch(InterruptedException e){e.printStackTrace();}
System.out.println(Thread.currentThread().getName()+"...sale..."+num--);//1
}
}
}
class test{
public static void main(String[] args){
Ticket t = new Ticket();
Thread t1 = new Thread(t);
Thread t2 = new Thread(t);
t1.start();
//t1先啟動,但是他并不一定能搶到CPU,主線程依舊拿著CPU
//主線程拿著CPU往下走,將flag改為了false,導致兩個
//線程同時用的一個任務(wù)代碼,即一把鎖,不會出現(xiàn)安全問題,所以,應該在此處
//讓主線程進入睡眠狀態(tài),主線程放棄CPU,然后t1立刻拿到CPU,
//這樣t1就可以,在flag是true的情況下,進入同步代碼塊中執(zhí)行
//所以t1用的就是obj鎖,然后主線程再拿上CPU,將flag改為false
//t2拿上CPU時,flag就為false,所以進入的是同步函數(shù)中執(zhí)行,
//同步函數(shù)用的鎖是this,兩把鎖,肯定會出現(xiàn)線程安全問題,所以,
//如果想解決安全問題,將同步代碼塊的鎖,也改為this,即可解決
//讓主線程放棄CPU
try{
Thread.sleep(20);
}catch(InterruptedException e){
e.printStackTrace();
}
t.flag = false;
t2.start();
}
}
總結(jié)
同步函數(shù)的鎖是this,靜態(tài)同步函數(shù)的鎖是他所屬類的字節(jié)碼文件對象。
以上就是本文關(guān)于Java同步函數(shù)代碼詳解的全部內(nèi)容,希望對大家有所幫助,感興趣的朋友可以參閱:Java多線程ForkJoinPool實例詳解 Java通過賣票理解多線程 Java線程安全基礎(chǔ)概念解析等,感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
Java數(shù)據(jù)結(jié)構(gòu)二叉樹難點解析
樹是一種重要的非線性數(shù)據(jù)結(jié)構(gòu),直觀地看,它是數(shù)據(jù)元素(在樹中稱為結(jié)點)按分支關(guān)系組織起來的結(jié)構(gòu),很象自然界中的樹那樣。樹結(jié)構(gòu)在客觀世界中廣泛存在,如人類社會的族譜和各種社會組織機構(gòu)都可用樹形象表示2021-10-10
SpringBoot整合Graylog做日志收集實現(xiàn)過程
這篇文章主要為大家介紹了SpringBoot整合Graylog做日志收集實現(xiàn)過程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-12-12
Java連接數(shù)據(jù)庫步驟解析(Oracle、MySQL)
本文主要介紹了Java連接Oracle數(shù)據(jù)庫和MySQL數(shù)據(jù)庫的步驟解析。具有很好的參考價值,需要的朋友一起來看下吧2016-12-12
Java System.getProperty()-獲取系統(tǒng)參數(shù)案例詳解
這篇文章主要介紹了Java System.getProperty()-獲取系統(tǒng)參數(shù)案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-08-08

