亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

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

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

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

NEW: 安排了工作, 還未開始行動(dòng)

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

BLOCKED: 這幾個(gè)都表示排隊(duì)等著其他事情

WAITING: 這幾個(gè)都表示排隊(duì)等著其他事情

TIMED_WAITING: 這幾個(gè)都表示排隊(duì)等著其他事情

TERMINATED: 工作完成了.

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

NEW:Thread對(duì)象有了,但是PCB還沒有

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

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

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

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

TERMINATED:對(duì)象還在,但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("線程啟動(dòng)前:" + t.getState());
 
        t.start();
        while (t.isAlive()){
            System.out.println("線程運(yùn)行中:" + t.getState());
        }
        System.out.println("線程結(jié)束后:" + t.getState());
    }

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

線程不安全的原因

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

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

②自增操作不是原子的

每次++都能拆成三個(gè)步驟

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

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

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

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

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

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

③多個(gè)線程嘗試修改同一個(gè)變量

如果是一個(gè)線程修改一個(gè)變量,線程安全

如果多個(gè)線程讀取同一個(gè)變量,線程安全

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

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

⑤指令重排序

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

四,解決線程安全問題

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

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("輸入一個(gè)整數(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就會(huì)一直在鎖這里阻塞等待

 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("輸入一個(gè)整數(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("輸入一個(gè)整數(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();
    }

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

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

相關(guān)文章

  • Java連接redis報(bào)錯(cuò)timed?out問題的解決辦法

    Java連接redis報(bào)錯(cuò)timed?out問題的解決辦法

    最近項(xiàng)目開發(fā)中用到了Redis,下面這篇文章主要給大家介紹了關(guān)于Java連接redis報(bào)錯(cuò)timed?out問題的解決辦法,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-02-02
  • Java中常用的四種引用類型詳解

    Java中常用的四種引用類型詳解

    Java中常用的四種引用類型,分別為,強(qiáng)引用、軟引用、弱引用以及虛引用,這篇文章主要為大家介紹了這四種引用的用法,需要的可以參考一下
    2023-06-06
  • @valid 無法觸發(fā)BindingResult的解決

    @valid 無法觸發(fā)BindingResult的解決

    這篇文章主要介紹了@valid 無法觸發(fā)BindingResult的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Hibernate連接三種數(shù)據(jù)庫的配置文件

    Hibernate連接三種數(shù)據(jù)庫的配置文件

    今天小編就為大家分享一篇關(guān)于Hibernate連接三種數(shù)據(jù)庫的配置文件,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-03-03
  • spring循環(huán)依賴策略解析

    spring循環(huán)依賴策略解析

    這篇文章主要為大家詳細(xì)介紹了spring循環(huán)依賴策略,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • java中dart類詳細(xì)講解

    java中dart類詳細(xì)講解

    這篇文章主要介紹了dart類詳細(xì)講解,實(shí)例講解的很清晰,有對(duì)于這方面不太清楚的同學(xué)可以跟著學(xué)習(xí)下
    2021-02-02
  • SpringBoot接收前端參數(shù)的幾種方式分享

    SpringBoot接收前端參數(shù)的幾種方式分享

    這篇文章給大家分享幾種SpringBoot接收前端參數(shù)的方式,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-09-09
  • 基于java中正則操作的方法總結(jié)

    基于java中正則操作的方法總結(jié)

    本篇文章介紹了,在java中正則操作的方法總結(jié)。需要的朋友參考下
    2013-05-05
  • SpringBoot詳解如果通過@Value注解給靜態(tài)變量注入值

    SpringBoot詳解如果通過@Value注解給靜態(tài)變量注入值

    這篇文章主要介紹了springboot如何通過@Value給靜態(tài)變量注入值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 高分面試從Hotspot源碼層面剖析java多態(tài)實(shí)現(xiàn)原理

    高分面試從Hotspot源碼層面剖析java多態(tài)實(shí)現(xiàn)原理

    這篇文章主要為大家介紹了在面試中從Hotspot源碼層面來剖析java多態(tài)的實(shí)現(xiàn)原理,這樣回答薪資隨你開,有需要的朋友可以借鑒參考下,希望大家多多加薪
    2022-01-01

最新評(píng)論