最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中的線程安全問(wèn)題詳細(xì)解析

 更新時(shí)間:2023年11月17日 10:16:58   作者:牧碼ya  
這篇文章主要介紹了Java中的線程安全問(wèn)題詳細(xì)解析,線程安全是如果有多個(gè)線程在同時(shí)運(yùn)行,而這些線程可能會(huì)同時(shí)運(yùn)行這段代碼,程序每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,此時(shí)我們就稱之為是線程安全的,需要的朋友可以參考下

線程安全

線程安全:如果有多個(gè)線程在同時(shí)運(yùn)行,而這些線程可能會(huì)同時(shí)運(yùn)行這段代碼。程序每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,而且其他的變量的值也和預(yù)期的是一樣的,此時(shí)我們就稱之為是線程安全的。

我們通過(guò)一個(gè)案例,演示線程的安全問(wèn)題:

電影院賣票,使用了A、B、C三個(gè)窗口進(jìn)行賣票,電影票總數(shù)為100張

采用線程對(duì)象來(lái)模擬賣票窗口A、B、C;使用Runnable接口的子類來(lái)模擬買的電影票

模擬電影票:

public class Ticket implements Runnable{
    // 在成員位置 定義票的總數(shù)100
    int ticket = 100;

    @Override
    public void run() {
        // 模擬買票窗口
        // 買票窗口永遠(yuǎn)開啟
        while (true){
            // 判斷是否還有票可以賣
            if(ticket > 0){
                // 使用sleep增加“程序的時(shí)間”--每張票賣50ms
                try {
                    Thread.sleep(50);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                // 獲得線程名稱 即買票窗口名稱
                String name = Thread.currentThread().getName();
                System.out.println(name + "賣掉第" + ticket-- + "票");
            }
        }
    }
}

模擬買票:

/**
 * 模擬買票操作
 *    假設(shè)一場(chǎng)電影有100張票
 *    三個(gè)窗口同時(shí)買票
 *
 *    窗口  線程對(duì)象
 *    買票  線程任務(wù) 實(shí)現(xiàn)runnable接口
 */
public class Demo {
    public static void main(String[] args) {
        // 創(chuàng)建買票任務(wù)對(duì)象
        Ticket ticket = new Ticket();

        // 創(chuàng)建三個(gè)窗口
        Thread t1 = new Thread(ticket, "窗口A");
        Thread t2 = new Thread(ticket, "窗口B");
        Thread t3 = new Thread(ticket, "窗口C");

        // 開啟線程
        t1.start();
        t2.start();
        t3.start();
    }
}

運(yùn)行結(jié)果:

窗口A賣掉第100張票
窗口C賣掉第98張票
窗口B賣掉第99張票
窗口A賣掉第97張票
窗口B賣掉第95張票
窗口C賣掉第96張票
窗口C賣掉第94張票 ⇐
窗口B賣掉第94張票 ⇐
窗口A賣掉第94張票 ⇐
...
窗口C賣掉第1張票
窗口A賣掉第0張票
窗口B賣掉第-1張票 ⇐

發(fā)現(xiàn)程序出現(xiàn)了兩個(gè)問(wèn)題:

1. 相同的票數(shù)被賣了多次,如第94張被三個(gè)窗口都賣了

2. 賣出了不存在的票,如窗口B賣掉了第-1張票

此時(shí),幾個(gè)窗口(線程)票數(shù)不同步了,這種問(wèn)題稱為線程不安全。

線程安全問(wèn)題都是有全局變量即靜態(tài)變量引起的。若每個(gè)線程中對(duì)全局變量、靜態(tài)變量只有讀操作,而無(wú)寫操作。一般來(lái)說(shuō),這個(gè)全局變量是線程安全的;若有多個(gè)線程同時(shí)執(zhí)行寫操作,一般都需要考慮線程同步,否則的話就可能影響線程安全

線程同步

當(dāng)我們使用多個(gè)線程訪問(wèn)同一資源的時(shí)候,且多個(gè)線程中對(duì)資源有些的操作,就容易出現(xiàn)線程安全問(wèn)題

要解決上述多想成并發(fā)訪問(wèn)一個(gè)資源的安全性問(wèn)題:也就是解決重復(fù)賣同一張票和賣不存在的票問(wèn)題,Java中提供了同步機(jī)制(synchronized)來(lái)解決

根據(jù)案例簡(jiǎn)述:

窗口A線程進(jìn)入操作(買票)的時(shí)候,窗口B和窗口C線程只能在外等著,窗口A操作結(jié)束,窗口A、窗口B和窗口C(CPU分配內(nèi)存是隨機(jī)的,所以還有可能是窗口A進(jìn)入)才有機(jī)會(huì)進(jìn)入代碼去執(zhí)行。

也就是說(shuō),在某個(gè)線程修改共享資源的時(shí)候,其他線程不能修改該資源,等待修改完畢同步之后,才能去搶奪CPU資源,完成對(duì)應(yīng)的操作,保證了數(shù)據(jù)的同步性,解決了線程不安全的現(xiàn)象。

為了保證每個(gè)線程都能正常執(zhí)行原子操作,Java引入了線程同步機(jī)制。

有三種方式完成同步操作:

1. 同步代碼塊

2. 同步方法

3. 鎖機(jī)制

同步代碼塊

同步代碼塊:synchronized 關(guān)鍵字可以用于方法中的某個(gè)區(qū)塊中,表示只對(duì)這個(gè)區(qū)塊的資源實(shí)行互斥訪問(wèn)。

格式:

synchronized(同步鎖){
    // 需要同步的操作的代碼
}

同步鎖:

對(duì)象的同步鎖只是一個(gè)概念,可以想象為在對(duì)象上標(biāo)記了一個(gè)鎖。

1. 鎖對(duì)象可以是任意類型

2. 多個(gè)線程對(duì)象要使用同一把鎖

注意:在任何時(shí)候,最多允許一個(gè)線程擁有同步鎖,誰(shuí)拿到就進(jìn)入代碼塊,其他的線程只能在外等著

使用同步代碼塊解決賣票問(wèn)題:

/**
 * synchronized(鎖對(duì)象){
 *
 * }
 * 1. 鎖對(duì)象可以是任意類型
 * 2. 互斥線程需要使用同一把鎖
 */
public class Ticket implements Runnable{
    // 在成員位置 定義票的總數(shù)100
    int ticket = 100;

    Object obj = new Object();

    @Override
    public void run() {
        // 模擬買票窗口
        // 買票窗口永遠(yuǎn)開啟
        while (true){
            // 同步鎖
            synchronized (obj){
                // 判斷是否還有票可以賣
                if(ticket > 0){
                    // 使用sleep增加“程序的時(shí)間”--每張票賣50ms
                    try {
                        Thread.sleep(50);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    // 獲得線程名稱 即買票窗口名稱
                    String name = Thread.currentThread().getName();
                    System.out.println(name + "賣掉第" + ticket-- + "票");
                }
            }

        }
    }
}

執(zhí)行結(jié)果:

窗口A賣掉第100票
窗口C賣掉第99票
窗口B賣掉第98票
窗口B賣掉第97票
...
窗口C賣掉第4票
窗口A賣掉第3票
窗口A賣掉第2票
窗口A賣掉第1票

此時(shí),每張票都只會(huì)被賣掉一次,不會(huì)存在賣掉不存在的電影票的問(wèn)題。

當(dāng)使用了同步代碼塊后,上述的線程的安全問(wèn)題即可解決

到此這篇關(guān)于Java中的線程安全問(wèn)題詳細(xì)解析的文章就介紹到這了,更多相關(guān)Java線程安全內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java?使用readLine()?亂碼的解決

    java?使用readLine()?亂碼的解決

    這篇文章主要介紹了java使用readLine()亂碼的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 淺談Hibernate對(duì)象狀態(tài)之間的神奇轉(zhuǎn)換

    淺談Hibernate對(duì)象狀態(tài)之間的神奇轉(zhuǎn)換

    這篇文章主要介紹了淺談Hibernate對(duì)象狀態(tài)之間的神奇轉(zhuǎn)換,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • 一文盤點(diǎn)SpringBoot中常用跨域處理方案

    一文盤點(diǎn)SpringBoot中常用跨域處理方案

    跨域是瀏覽器為了保障安全而遵循的一種規(guī)則,是同源策略的一部分,本文將為大家整理了SpringBoot中常用跨域處理的方法,需要的小伙伴可以了解下
    2025-08-08
  • Spring Security十分鐘入門教程

    Spring Security十分鐘入門教程

    這篇文章主要介紹了Spring Security入門教程,Spring Security是一個(gè)能夠?yàn)榛赟pring的企業(yè)應(yīng)用系統(tǒng)提供聲明式的安全訪問(wèn)控制解決方案的安全框架
    2022-09-09
  • java GUI編程之paint繪制操作示例

    java GUI編程之paint繪制操作示例

    這篇文章主要介紹了java GUI編程之paint繪制操作,結(jié)合實(shí)例形式詳細(xì)分析了java GUI編程paint繪制相關(guān)操作技巧與使用注意事項(xiàng),需要的朋友可以參考下
    2020-01-01
  • java遞歸實(shí)現(xiàn)樹形結(jié)構(gòu)數(shù)據(jù)完整案例

    java遞歸實(shí)現(xiàn)樹形結(jié)構(gòu)數(shù)據(jù)完整案例

    遞歸算法的代碼比較簡(jiǎn)潔,可讀性較好;但是在實(shí)際的業(yè)務(wù)處理中會(huì)出現(xiàn)多次的重復(fù)調(diào)用,如果處理不好,很容易出現(xiàn)StackOverflowError報(bào)錯(cuò),這篇文章主要給大家介紹了關(guān)于java遞歸實(shí)現(xiàn)樹形結(jié)構(gòu)數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • Java多線程中的wait與notify方法詳解

    Java多線程中的wait與notify方法詳解

    這篇文章主要介紹了Java多線程中的wait與notify方法詳解,線程的調(diào)度是無(wú)序的,但有些情況要求線程的執(zhí)行是有序的,因此,我們可以使用 wait() 方法來(lái)使線程執(zhí)行有序,需要的朋友可以參考下
    2023-08-08
  • 快速了解Spring Boot

    快速了解Spring Boot

    這篇文章主要介紹了快速了解Spring Boot,介紹了其環(huán)境準(zhǔn)備,URL中的變量以及模板渲染等內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • IDEA編譯亂碼Build Output提示信息亂碼

    IDEA編譯亂碼Build Output提示信息亂碼

    IDEA編譯的時(shí)候亂碼,Build Output提示信息亂碼,本文就詳細(xì)的介紹一下解決方法,有需要的同學(xué)可以了解一下
    2021-06-06
  • Mybatis如何實(shí)現(xiàn)InsertOrUpdate功能

    Mybatis如何實(shí)現(xiàn)InsertOrUpdate功能

    這篇文章主要介紹了Mybatis如何實(shí)現(xiàn)InsertOrUpdate功能,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-05-05

最新評(píng)論

闸北区| 镇宁| 宽甸| 千阳县| 霸州市| 卢氏县| 张家川| 许昌县| 郓城县| 东安县| 璧山县| 海口市| 枣强县| 大竹县| 郯城县| 黎川县| 沈阳市| 榆中县| 罗平县| 大悟县| 通州区| 孟村| 阳西县| 鹤岗市| 凌海市| 陆良县| 海盐县| 塘沽区| 绍兴县| 田林县| 岳普湖县| 江永县| 凤冈县| 宁远县| 阿克陶县| 赞皇县| 天津市| 策勒县| 蚌埠市| 濮阳县| 浦东新区|