欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java 詳細(xì)講解線程安全與同步附實(shí)例與注釋

 更新時(shí)間:2022年04月14日 10:11:05   作者:湯鍵.TJ  
線程安全是多線程編程時(shí)的計(jì)算機(jī)程序代碼中的一個(gè)概念。在擁有共享數(shù)據(jù)的多條線程并行執(zhí)行的程序中,線程安全的代碼會(huì)通過同步機(jī)制保證各個(gè)線程都可以正常且正確的執(zhí)行,不會(huì)出現(xiàn)數(shù)據(jù)污染等意外情況

線程安全問題

多個(gè)線程可能會(huì)共享(訪問)同一個(gè)資源

比如訪問同一個(gè)對(duì)象,同一個(gè)變量,同一個(gè)文件

當(dāng)多個(gè)線程訪問同一塊資源時(shí),很容易引發(fā)數(shù)據(jù)錯(cuò)亂和數(shù)據(jù)安全問題,稱為線程安全問題

什么情況下會(huì)出現(xiàn)線程安全問題

多個(gè)線程共享同一個(gè)資源

且至少有一個(gè)線程正在執(zhí)行寫的操作

實(shí)例:

存錢取錢問題

分別有存錢和取錢2個(gè)線程

   存錢                      取錢
   線程1         余額         線程2
   1000  《----1000------》 1000
   1000+1000-----》2000
                500 《-----1000-500

正確:結(jié)束后余額應(yīng)該是1500,而不是500

買票問題

有賣票2個(gè)線程

   賣票                      賣票
   線程1         票數(shù)         線程2
   1000  《----1000------》 1000
   1000-1-----》999
                999 《-----1000-1

正確:結(jié)束后余額應(yīng)該是998,而不是999

買票問題錯(cuò)誤(未線程同步)實(shí)例:

public class love implements Runnable{
    private int piao=3000;//有3000張票
    public boolean sale() {//ture代表還有票;false代表沒有票了
        if(piao<1) return false;
         piao--;//賣1張票
         
         //細(xì)化piao--;
         //寄存器=piao;
         //寄存器=寄存器-1;
         //piao=寄存器;
         
         String sk =Thread.currentThread().getName();//獲取當(dāng)前線程(買票窗口)的名字
         System.out.println(sk+"賣了1張票,還剩下"+piao+"張");
         return piao>1;
    }
    public void run() {
         while(sale());//循環(huán)執(zhí)行;直至賣完票返回false
    }
}
 
public class Main {
    public static void main(String[] a) {
        love tjlove =new love();
        for(int i=1;i<=4;i++) {//循環(huán)4次;產(chǎn)生4個(gè)線程(窗口)賣票
            Thread tj = new Thread(tjlove());
            tj.setName(""+i);
            tj.start();
        }
    }
}

部分輸出結(jié)果:

線程安全問題

分析問題

線程A和B對(duì)類中1個(gè)變量值為17進(jìn)行+1操作
最終結(jié)果為2個(gè)18

解決方案

加鎖:

過程:首先線程A先訪問到這個(gè)17,讀上來后進(jìn)行加鎖并進(jìn)去+1的操作改為18
并且17在加鎖期間其它線程都不能訪問
改完之后再進(jìn)行寫入,然后再解鎖17
然后再由線程B去訪問它,再進(jìn)行加鎖,重復(fù)上面操作變成19再解鎖
這樣做能保證在同一時(shí)間只有1個(gè)線程去訪問它,這樣就保證了安全;之前錯(cuò)誤是由于這些線程一起去訪問了它

線程同步

剛剛所說的加鎖操作便是線程同步技術(shù)

可以使用線程同步技術(shù)來解決線程安全問題

線程同步在Java里有2種做法:

1.同步語句

2.同步方法

同步語句

public class love implements Runnable{
	private int piao=3000;//本人cpu單核性能過強(qiáng),數(shù)據(jù)量大些才能看到是4個(gè)線程在賣票
	public boolean sale() {
		synchronized(this) {//1個(gè)線程獲取這個(gè)對(duì)象的鎖,并加鎖;    synchronized作用于整個(gè)語句
		//this指向當(dāng)前對(duì)象
		//不能用new Object();這樣會(huì)產(chǎn)生新的對(duì)象,產(chǎn)生新的鎖
		//把this換成"123",效果基本一樣;因?yàn)槠浯嬖诔A恐道?,每次訪問的對(duì)象一樣
			if(piao<1) return false;
			piao--;
			String sk =Thread.currentThread().getName();
			System.out.println(sk+"賣了1張票,還剩下"+piao+"張");
			return piao>0;
			}
	}
	public void run() {
		 while(sale());
	}
}

部分輸出結(jié)果:

synchronize(obj)的原理

1.每個(gè)對(duì)象都有一個(gè)與它相關(guān)的內(nèi)部鎖(intrinsic lock)或者叫監(jiān)視器鎖(monitor lock)

2.第一個(gè)執(zhí)行到同步語句的線程可以獲得 obj 的內(nèi)部鎖,在執(zhí)行完同步語句中的代碼后釋放此鎖

3.只要一個(gè)線程持有了內(nèi)部鎖,那么其它線程在同一時(shí)刻將無法再獲得此鎖

? 當(dāng)它們?cè)噲D獲取此鎖時(shí),將會(huì)進(jìn)入BLOCKED狀態(tài)

4.多個(gè)線程訪問同一個(gè) synchronized(obj)語句時(shí)

obj必須是同一個(gè)對(duì)象,才能起到同步的作用

同步方法

public class love implements Runnable{
    private int piao=3000;
    public synchronized boolean sale() { //synchronized作用于整個(gè)方法
            if(piao<1) return false;
            piao--;
            String sk =Thread.currentThread().getName();
            System.out.println(sk+"賣了1張票,還剩下"+piao+"張");
            return piao>0;
    }
    public void run() {
         while(sale());
    }
}

synchronized不能修飾構(gòu)造方法

同步方法的本質(zhì)

實(shí)例方法:synchronized (this)

靜態(tài)方法:synchronized (Class對(duì)象)

同步語句比同步方法更靈活一點(diǎn)

同步語句可以精確控制需要加鎖的代碼范圍,減少處于BLOCKED狀態(tài)的線程,充分利用勞動(dòng)力

使用了線程同步技術(shù)后

雖然解決了線程安全問題,但是降低了程序的執(zhí)行效率

因?yàn)榧恿随i就會(huì)有處于等待的線程,多了加鎖解鎖的操作

所以在真正有必要的時(shí)候,才使用線程同步技術(shù)

到此這篇關(guān)于Java 詳細(xì)講解線程安全與同步附實(shí)例與注釋的文章就介紹到這了,更多相關(guān)Java 線程安全內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java提示缺少返回語句的解決辦法

    Java提示缺少返回語句的解決辦法

    在本篇文章里小編給大家分享了關(guān)于Java提示缺少返回語句的解決辦法以及相關(guān)知識(shí)點(diǎn),需要的朋友們參考下。
    2019-07-07
  • Flutter實(shí)現(xiàn)文本組件、圖標(biāo)及按鈕組件的代碼

    Flutter實(shí)現(xiàn)文本組件、圖標(biāo)及按鈕組件的代碼

    這篇文章主要介紹了Flutter實(shí)現(xiàn)文本組件、圖標(biāo)及按鈕組件的代碼,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下
    2019-07-07
  • IDEA 工程里 new不出來Vue文件的圖文解決方案

    IDEA 工程里 new不出來Vue文件的圖文解決方案

    這篇文章主要介紹了IDEA 工程里 new不出來Vue文件的解決方案,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-03-03
  • MyBatis-Plus聯(lián)表查詢以及分頁代碼實(shí)例

    MyBatis-Plus聯(lián)表查詢以及分頁代碼實(shí)例

    在開發(fā)中遇到了一個(gè)問題,需要進(jìn)行聯(lián)表查詢并進(jìn)行分頁,因?yàn)椴幌胱约簛韺懛猪?所以還是依靠MybatisPlus來實(shí)現(xiàn)想要的功能,下面這篇文章主要給大家介紹了關(guān)于MyBatis-Plus聯(lián)表查詢以及分頁的相關(guān)資料,需要的朋友可以參考下
    2023-06-06
  • mybatis如何處理返回結(jié)果集

    mybatis如何處理返回結(jié)果集

    這篇文章主要介紹了mybatis如何處理返回結(jié)果集問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 如何正確控制springboot中bean的加載順序小結(jié)篇

    如何正確控制springboot中bean的加載順序小結(jié)篇

    這篇文章主要介紹了如何正確控制springboot中bean的加載順序總結(jié),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-07-07
  • java實(shí)現(xiàn)酒店管理系統(tǒng)

    java實(shí)現(xiàn)酒店管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)酒店管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-02-02
  • Java遞歸讀取文件例子_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java遞歸讀取文件例子_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    本文通過一段示例代碼給大家介紹了java遞歸讀取文件的方法,代碼簡(jiǎn)單易懂,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友參考下吧
    2017-05-05
  • MybatisPlus多表連接查詢的問題及解決方案

    MybatisPlus多表連接查詢的問題及解決方案

    MybatisPlus官方并沒有提供多表連接查詢的通用解決方案,然而連接查詢是相當(dāng)普遍的需求,今天通過本文給大家介紹下MybatisPlus多表連接查詢的問題及解決方案,感興趣的朋友一起看看吧
    2022-01-01
  • 基于idea把springboot項(xiàng)目部署到docker

    基于idea把springboot項(xiàng)目部署到docker

    這篇文章主要介紹了基于idea把springboot項(xiàng)目部署到docker,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01

最新評(píng)論