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

Java線程安全狀態(tài)專題解析

 更新時間:2022年03月02日 14:27:18   作者:/少司命  
線程安全是多線程編程時的計算機程序代碼中的一個概念。在擁有共享數(shù)據(jù)的多條線程并行執(zhí)行的程序中,線程安全的代碼會通過同步機制保證各個線程都可以正常且正確的執(zhí)行,不會出現(xiàn)數(shù)據(jù)污染等意外情況

一、觀察線程的所有狀態(tài)

線程的狀態(tài)是一個枚舉類型 Thread.State

 public static void main(String[] args) {
        for (Thread.State state : Thread.State.values()){
            System.out.println(state);
        }
    }

NEW: 安排了工作, 還未開始行動

RUNNABLE: 可工作的. 又可以分成正在工作中和即將開始工作.就緒狀態(tài)

BLOCKED: 這幾個都表示排隊等著其他事情

WAITING: 這幾個都表示排隊等著其他事情

TIMED_WAITING: 這幾個都表示排隊等著其他事情

TERMINATED: 工作完成了.

二、線程狀態(tài)和狀態(tài)轉(zhuǎn)移的意義

NEW:Thread對象有了,但是PCB還沒有

RUNNABLE:線程正在CPU上執(zhí)行或者即將到CPU上執(zhí)行(PCB在就緒隊列中,隨時可能被調(diào)度到)

WAITING:wait方法導(dǎo)致

TIMED_WAITING:sleep方法導(dǎo)致

BLOCKED:等待鎖導(dǎo)致

TERMINATED:對象還在,但PCB已經(jīng)沒了

public static void main(String[] args) {
        Thread t = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 100_00; i++){
 
                }
            }
        };
        System.out.println("線程啟動前:" + t.getState());
 
        t.start();
        while (t.isAlive()){
            System.out.println("線程運行中:" + t.getState());
        }
        System.out.println("線程結(jié)束后:" + t.getState());
    }

三、多線程帶來的風(fēng)險

線程不安全的原因

①線程是搶占式執(zhí)行的

線程不安全的萬惡之源,線程之間的調(diào)度完全由內(nèi)核負責(zé),用戶代碼中感知不到,也無法控制。線程之間誰先執(zhí)行,誰后執(zhí)行,誰執(zhí)行到哪里從CPU上下來,這樣的過程用戶無法控制也無法感知到的。

②自增操作不是原子的

每次++都能拆成三個步驟

? ? ? ? 把內(nèi)存中的數(shù)據(jù)讀取到CPU中

? ? ? ? 把CPU中的數(shù)據(jù)+1

? ? ? ? 把計算的數(shù)據(jù)寫回內(nèi)存中

如果兩個線程串行執(zhí)行,此時計算結(jié)果為2。

如果兩個線程并行執(zhí)行,線程1進行++操作到一半的時候,線程也進行了++操作,此時自增兩次,但結(jié)果為1。

必須保證線程1save結(jié)束了,線程2再load,此時計算結(jié)果才正確

③多個線程嘗試修改同一個變量

如果是一個線程修改一個變量,線程安全

如果多個線程讀取同一個變量,線程安全

如果多個線程修改不同的變量。線程安全

④內(nèi)存可見性導(dǎo)致線程安全問題

⑤指令重排序

Java的編譯器在編譯代碼時,會對指令進行優(yōu)化,調(diào)整指令的先后順序,保證原有的邏輯不變的情況下,提高程序的運行效率

四,解決線程安全問題

鎖-synchronized

未加鎖

static class Counter{
        public int count = 0;
 
         public void increase(){
            count++;
        }
    }
 
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++){
                    counter.increase();
                }
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++){
                    counter.increase();
                }
            }
        };
        t1.start();
        t2.start();
        t1.join();
        t2.join();
 
        System.out.println(counter.count);
    }

?已加鎖

static class Counter{
        public int count = 0;
 
        synchronized public void increase(){
            count++;
        }
    }
 
    public static void main(String[] args) throws InterruptedException {
        Counter counter = new Counter();
        Thread t1 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++){
                    counter.increase();
                }
            }
        };
        Thread t2 = new Thread(){
            @Override
            public void run() {
                for (int i = 0; i < 50000; i++){
                    counter.increase();
                }
            }
        };
        t1.start();
        t2.start();
        t1.join();
        t2.join();
 
        System.out.println(counter.count);
    }

此處的synchronized就是針對counter這個對象來加鎖,進入increase方法內(nèi)部,就把加鎖狀態(tài)設(shè)為ture,increase方法退出之后,就把加鎖狀態(tài)設(shè)為false,如果某個線程已經(jīng)把加鎖狀態(tài)設(shè)為ture,此處的其他的線程嘗試去加鎖,就會阻塞

synchronized的特性——刷新內(nèi)存

synchronized 的工作過程:

????????1. 獲得互斥鎖

????????2. 從主內(nèi)存拷貝變量的最新副本到工作的內(nèi)存

????????3. 執(zhí)行代碼

????????4. 將更改后的共享變量的值刷新到主內(nèi)存

????????5. 釋放互斥鎖

synchronized的特性——互斥

 public static void main(String[] args) {
        Object locker = new Object();
 
        Thread t1 = new Thread(){
            @Override
            public void run() {
                Scanner scanner = new Scanner(System.in);
                synchronized (locker) {
                    System.out.println("輸入一個整數(shù)");
                    int num = scanner.nextInt();
                    System.out.println("num= " + num);
                }
            }
        };
        t1.start();
 
        Thread t2 = new Thread(){
            @Override
            public void run() {
                while (true){
                    synchronized (locker){
                        System.out.println("線程2獲取到鎖");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        t2.start();
    }

一旦線程一獲取到鎖,并且沒有釋放的話,線程2就會一直在鎖這里阻塞等待

 public static void main(String[] args) {
        Object locker1 = new Object();
        Object locker2 = new Object();
 
        Thread t1 = new Thread(){
            @Override
            public void run() {
                Scanner scanner = new Scanner(System.in);
                synchronized (locker1) {
                    System.out.println("輸入一個整數(shù)");
                    int num = scanner.nextInt();
                    System.out.println("num= " + num);
                }
            }
        };
        t1.start();
 
        Thread t2 = new Thread(){
            @Override
            public void run() {
                while (true){
                    synchronized (locker2){
                        System.out.println("線程2獲取到鎖");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        t2.start();
    }

?不是同一把鎖,就不回出現(xiàn)競爭,就沒有互斥了。

public static void main(String[] args) {
        Object locker1 = new Object();
        Object locker2 = new Object();
 
        Thread t1 = new Thread(){
            @Override
            public void run() {
                Scanner scanner = new Scanner(System.in);
                synchronized (locker1.getClass()) {
                    System.out.println("輸入一個整數(shù)");
                    int num = scanner.nextInt();
                    System.out.println("num= " + num);
                }
            }
        };
        t1.start();
 
        Thread t2 = new Thread(){
            @Override
            public void run() {
                while (true){
                    synchronized (locker2.getClass()){
                        System.out.println("線程2獲取到鎖");
                        try {
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        };
        t2.start();
    }

這個代碼中,兩個線程都在針對locker1和locker2的類對象進行競爭,此處的locker1和locker2的類型都是Object,對應(yīng)的對象都是相同的對象。?

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

相關(guān)文章

  • Java訪問者模式實現(xiàn)優(yōu)雅的對象結(jié)構(gòu)處理

    Java訪問者模式實現(xiàn)優(yōu)雅的對象結(jié)構(gòu)處理

    Java訪問者模式是一種行為型設(shè)計模式,它通過將數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)操作分離,實現(xiàn)對復(fù)雜對象結(jié)構(gòu)的處理。它將數(shù)據(jù)結(jié)構(gòu)中的每個元素都轉(zhuǎn)換為訪問者能夠識別的形式,從而使得數(shù)據(jù)操作可以在不影響數(shù)據(jù)結(jié)構(gòu)的前提下進行擴展和變化
    2023-04-04
  • 將Dubbo服務(wù)打包成Jar包的操作步驟

    將Dubbo服務(wù)打包成Jar包的操作步驟

    Dubbo 是一款流行的 Java RPC 框架,它提供了高性能、透明化的 RPC 遠程服務(wù)調(diào)用方案,在開發(fā)基于 Dubbo 的服務(wù)時,我們通常需要將服務(wù)代碼打包成可發(fā)布的 JAR 包,本文將詳細介紹如何將 Dubbo 服務(wù)打包成 JAR 包,并提供相應(yīng)的配置和步驟,需要的朋友可以參考下
    2024-12-12
  • 打印Java程序的線程棧信息方式

    打印Java程序的線程棧信息方式

    這篇文章主要介紹了打印Java程序的線程棧信息方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java中的Optional類用法詳細講解

    Java中的Optional類用法詳細講解

    這篇文章詳細介紹了Java中Optional類的使用,包括創(chuàng)建Optional對象,Optional對象的常用方法,如get、orElse、orElseGet、orElseThrow等,以及Optional類結(jié)合Lambda表達式和StreamAPI的使用,需要的朋友可以參考下
    2024-10-10
  • Mybatis返回單個實體或者返回List的實現(xiàn)

    Mybatis返回單個實體或者返回List的實現(xiàn)

    這篇文章主要介紹了Mybatis返回單個實體或者返回List的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Java中實現(xiàn)多重排序的幾種方法小結(jié)

    Java中實現(xiàn)多重排序的幾種方法小結(jié)

    Java中的多重排序通常指的是同時對一個集合中的兩個或更多列或多維度的數(shù)據(jù)進行排序,這通常通過自定義Comparator實現(xiàn),可以結(jié)合Arrays.sort()或Collections.sort()方法,當需要進行多重排序時,即根據(jù)多個字段進行排序,我們可以采用以下幾種方法
    2024-10-10
  • spring security獲取用戶信息的實現(xiàn)代碼

    spring security獲取用戶信息的實現(xiàn)代碼

    這篇文章主要介紹了spring security獲取用戶信息的實現(xiàn)代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-12-12
  • mybatis調(diào)用mysql存儲過程并獲取返回值方式

    mybatis調(diào)用mysql存儲過程并獲取返回值方式

    這篇文章主要介紹了mybatis調(diào)用mysql存儲過程并獲取返回值方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • java開發(fā)flyway的方法

    java開發(fā)flyway的方法

    這篇文章主要介紹了java開發(fā)flyway的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • Spring?c3p0配置的實現(xiàn)示例

    Spring?c3p0配置的實現(xiàn)示例

    在Spring框架中配置c3p0連接池可以提升數(shù)據(jù)庫操作性能,本文主要介紹了Spring?c3p0配置的實現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下
    2024-09-09

最新評論

元氏县| 保德县| 含山县| 临泉县| 尉氏县| 中江县| 池州市| 喀喇沁旗| 南昌市| 兴文县| 嘉定区| 牡丹江市| 中方县| 广宁县| 黄石市| 赤城县| 涡阳县| 响水县| 萨迦县| 海口市| 蒙城县| 迭部县| 临安市| 偏关县| 华安县| 长岛县| 章丘市| 桂林市| 岑巩县| 雷波县| 云阳县| 广宁县| 屏南县| 富顺县| 镇原县| 绿春县| 武功县| 富平县| 马关县| 庐江县| 英吉沙县|