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

Java并發(fā)編程進(jìn)階之線程控制篇

 更新時(shí)間:2022年07月18日 08:41:08   作者:陳橘又青  
在使用Java實(shí)際編程中,多線程可以說是無所不在,凡是需要并發(fā)執(zhí)行的都可以用到它,一個(gè)應(yīng)用程序中不用多線程將會(huì)是很糟糕的事情,所以掌握線程以及它的控制操作是非常重要的。通過本篇文章來今天帶大家一文掌握線程控制操作,感謝您的觀看

一、線程的基本概念

1.并行和并發(fā)

并行:多個(gè)CPU核心同時(shí)工作,處理不同的任務(wù)。

并發(fā):多個(gè)任務(wù)交替使用 CPU 核心工作,以提高 CPU 利用率。

2.進(jìn)程和線程

進(jìn)程:程序的一次執(zhí)行。由操作系統(tǒng)創(chuàng)建并分配資源,執(zhí)行一個(gè)單獨(dú)的任務(wù)。

進(jìn)程是系統(tǒng)進(jìn)行資源分配和調(diào)度的獨(dú)立單位,每個(gè)進(jìn)程都有自己的內(nèi)存空間和系統(tǒng)資源。進(jìn)程內(nèi)所有線程共享堆存儲(chǔ)空間,保存程序中定義的對(duì)象和常量池。

Windows系統(tǒng)中,每個(gè)運(yùn)行的 Java 程序都是一個(gè)獨(dú)立的進(jìn)程。

線程:進(jìn)程內(nèi)的執(zhí)行單元,不分配單獨(dú)的資源,執(zhí)行一個(gè)單獨(dú)的子任務(wù)。

線程是進(jìn)程內(nèi)調(diào)度和分派的基本單位,共享進(jìn)程資源。每個(gè)線程有自己的獨(dú)立的棧存儲(chǔ)空間,保存線程執(zhí)行的方法以及基本類型的數(shù)據(jù)。

運(yùn)行的 Java 程序內(nèi)含至少一個(gè)主線程 main ,用戶可以在 Java 程序中自定義并調(diào)用多個(gè)線程。 JVM 垃圾回收線程也是一個(gè)獨(dú)立的線程。

二、線程的運(yùn)行狀態(tài)

線程除創(chuàng)建狀態(tài) New 和結(jié)束狀態(tài) Terminate 外,主要有以下幾種運(yùn)行狀態(tài):

①運(yùn)行(Running) :CPU 正在執(zhí)行線程。

②就緒(Runnable) :線程一切就緒,等待 CPU 執(zhí)行。

運(yùn)行/就緒狀態(tài) 統(tǒng)稱為可運(yùn)行狀態(tài) Runnable。 Java 程序中,線程在 運(yùn)行/就緒狀態(tài) 之間的切換由 JVM 自動(dòng)調(diào)度,開發(fā)者無法獲知。線程之間的調(diào)度采用分優(yōu)先級(jí)多隊(duì)列時(shí)間片輪轉(zhuǎn)算法。進(jìn)程在執(zhí)行完 CPU 時(shí)間片切換到就緒狀態(tài)之前會(huì)先保存自己的狀態(tài),下次進(jìn)入運(yùn)行狀態(tài)時(shí)再重新加載。

③阻塞(Blocked) :線程因缺少其他資源,比如請(qǐng)求資源被上鎖而暫停執(zhí)行。在獲得資源后進(jìn)入就緒狀態(tài)。

④等待(Waitting) :線程接受了等待指令,釋放資源暫停執(zhí)行。在超時(shí)/接受喚醒指令后進(jìn)入就緒狀態(tài)。

三、線程操作實(shí)踐

Runnable 接口內(nèi)唯一聲明了 run 方法,由 Thread 類實(shí)現(xiàn)。開發(fā)者在 run 方法中定義運(yùn)行時(shí)線程將要執(zhí)行的功能,線程開啟后由Java虛擬機(jī)自動(dòng)調(diào)用并執(zhí)行。如果開發(fā)者主動(dòng)調(diào)用 run 方法,則只會(huì)當(dāng)作普通方法執(zhí)行。

1.線程兩種定義方法

①繼承 Thread 類,重寫 run 方法。

public class MyThread extends Thread {
   @Override
   public void run() {
       System.out.println(Thread.currentThread().getName());
   }
}

②實(shí)現(xiàn) Runnable 接口,實(shí)現(xiàn) run 方法。推薦使用,避免了單繼承的局限性。

public class MyThread implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

2.啟動(dòng)線程

Thread 類定義了 start 方法。調(diào)用 start 方法后,系統(tǒng)會(huì)開啟一個(gè)新線程進(jìn)入就緒狀態(tài):由 JVM 會(huì)自動(dòng)對(duì)線程進(jìn)行調(diào)度,在運(yùn)行時(shí)調(diào)用并執(zhí)行線程的 run 方法。一個(gè)線程只能啟動(dòng)一次。

①如果自定義線程類繼承 Thread 類,直接啟動(dòng)。

public class Main {
   public static void main(String[] args) {
       MyThread t1 = new MyThread();
       MyThread t2 = new MyThread("ThreadName");
       t1.start();
       t2.start();
   }
}

②如果自定義線程類實(shí)現(xiàn) Runnable 接口,則需要借助 Thread 類啟動(dòng)線程。

public class Main {
   public static void main(String[] args) {
       MyThread mythread = new MyThread();
       Thread t1 = new Thread(mythread);                   // 由系統(tǒng)指定默認(rèn)線程名 Thread-X
       Thread t2 = new Thread(mythread, "ThreadName");     // 開發(fā)者自定義線程名 
       t1.start();
       t2.start();
   }
}

3.同時(shí)定義和啟動(dòng)線程

通過匿名內(nèi)部類方式,我們可以實(shí)現(xiàn)同時(shí)定義和啟動(dòng)線程的簡(jiǎn)潔寫法。

public class Main {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable(){
            public void run(){
                System.out.println(Thread.currentThread().getName());
            }
        }).start();
    }
}
class Test {
   public void method() {
       System.out.println(Thread.currentThread().getName());
   }
}

4.線程彈出與暫停

Thread 類定義了 yield 方法。當(dāng)前線程執(zhí)行到 Thread.yield() 方法,會(huì)停止運(yùn)行進(jìn)入就緒狀態(tài)。但線程切換到就緒狀態(tài)后,什么時(shí)候被 JVM 調(diào)度回運(yùn)行狀態(tài)開發(fā)者無法控制。

public class ThreadDemo {
    public static void main(String[] args) {
       MyThread mythread = new MyThread();
       Thread t1 = new Thread(mythread);              
       Thread t2 = new Thread(mythread);    
       t1.start();
       t2.start();
    }
    static class MyThread implements Runnable {
        @Override
        public void run() {
            int count = 0;
            for (int i = 0; i < 10000; i++) {
                Thread.yield();                    // 切換到就緒狀態(tài)
                count++;
                System.out.println(count);
            }         
        }
    }
}

Thread 類定義了 sleep 方法。當(dāng)前線程執(zhí)行到 Thread.sleep(1000) 方法,會(huì)停止運(yùn)行進(jìn)入阻塞狀態(tài),但仍會(huì)保持對(duì)象鎖,其他線程不可訪問其資源。直到超時(shí)后進(jìn)入就緒狀態(tài)。調(diào)用 sleep 方法需要捕獲或拋出 InterruptException 異常。

public class ThreadDemo {
    public static void main(String[] args) {
       MyThread mythread = new MyThread();
       Thread t1 = new Thread(mythread);              
       Thread t2 = new Thread(mythread);    
       t1.start();
       t2.start();
    }
    static class MyThread implements Runnable {
        @Override
        public void run() {
            int count = 0;
            for (int i = 0; i < 10000; i++) {
                try{
                    Thread.sleep(1000);             // 當(dāng)前線程暫停 1s
                } catch(InterruptException e){
                    e.printStackTrace();
                }
                count++;
                System.out.println(count);
            }         
        }
    }
}

5.線程等待與喚醒

①線程等待

當(dāng)前線程執(zhí)行 obj.wait() 方法,線程會(huì)停止運(yùn)行并釋放對(duì)象鎖 obj,其他線程可以訪問其資源。同時(shí)線程進(jìn)入 obj 對(duì)象的等待池,直到被 notify 方法喚醒進(jìn)入就緒狀態(tài)。調(diào)用 wait 方法需要捕獲或拋出 InterruptException 異常。

wait 方法允許計(jì)時(shí)等待。當(dāng)前線程執(zhí)行 obj.wait(1000) 方法,計(jì)時(shí)結(jié)束后線程會(huì)被自動(dòng)喚醒進(jìn)入就緒狀態(tài)。

②線程喚醒

當(dāng)前線程執(zhí)行 obj.notify() 方法,會(huì)隨機(jī)從 obj 對(duì)象等待池中選擇一個(gè)線程喚醒,使其進(jìn)入就緒狀態(tài)。但是 notify 方法不會(huì)釋放當(dāng)前進(jìn)程的對(duì)象鎖,如果該線程持有 obj 對(duì)象的鎖,當(dāng)前線程釋放鎖后被喚醒的其他線程才能被執(zhí)行。如果想被喚醒線程先執(zhí)行,notify 方法后添加 wait 方法釋放鎖。

當(dāng)前線程執(zhí)行 obj.notifyall() 方法,會(huì)將所有 obj 對(duì)象等待池中所有線程喚醒。

public class ThreadDemo {
    public static void main(String[] args) {
        MyThread t = new MyThread("t");
        synchronized(t) {                         // 對(duì) t 設(shè)置對(duì)象鎖
            try {
                t.start();
                System.out.println("1");
                t.wait();                         // 當(dāng)前線程釋放 t 鎖,進(jìn)入 t 對(duì)象等待池
                System.out.println("4");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    static class MyThread extends Thread {
        @Override
        public void run() {
            synchronized (this) {                 // 對(duì) t 設(shè)置對(duì)象鎖        
                Thread.sleep(1000);
                System.out.println("2");
                this.notify();                    // 隨機(jī)喚醒一個(gè) t 對(duì)象等待池中的線程
                System.out.println("3");
            }
        }
    }
}

6.線程中斷

調(diào)用 t.stop() 方法可以強(qiáng)制終止線程 t 運(yùn)行,但強(qiáng)制中斷線程可能會(huì)造成意想不到的問題,已不推薦使用。

目前主要采用設(shè)置線程中斷標(biāo)志的方式,向線程發(fā)送中止信號(hào)。由線程自行終止運(yùn)行:

  • 執(zhí)行 t.interrupt() 方法,將線程 t 中斷標(biāo)志設(shè)為 true 。
  • 執(zhí)行 t.isInterrupted() 方法,查看線程 t 中斷標(biāo)志。
  • 執(zhí)行 t.interrupted() 方法,查看線程 t 中斷標(biāo)志然后將其設(shè)為 false 。
public class ThreadDemo {
    public static void main(String[] args) {
       MyThread mythread = new MyThread();
       Thread t = new Thread(mythread);              
       t.start();
       try {
            Thread.sleep(500);
        } catch (InterruptedException e) {}
       t.interrupt();                            // 設(shè)置中斷標(biāo)志為 true
    }
    static class MyThread implements Runnable {
        @Override
        public void run() {
            while (true) {
                System.out.print("hello");
                if(this.isInterrupted()){        // 查看中斷標(biāo)志,若為 true 結(jié)束循環(huán)
                    break;
                }
            }
        }        
    }
}

到此這篇關(guān)于Java并發(fā)編程進(jìn)階之線程控制篇的文章就介紹到這了,更多相關(guān)Java線程控制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot集成redis哨兵集群的實(shí)現(xiàn)示例

    springboot集成redis哨兵集群的實(shí)現(xiàn)示例

    本文主要介紹了springboot集成redis哨兵集群的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • 在已經(jīng)使用mybatis的項(xiàng)目里引入mybatis-plus,結(jié)果不能共存的解決

    在已經(jīng)使用mybatis的項(xiàng)目里引入mybatis-plus,結(jié)果不能共存的解決

    這篇文章主要介紹了在已經(jīng)使用mybatis的項(xiàng)目里引入mybatis-plus,結(jié)果不能共存的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • java連接SQL?Server數(shù)據(jù)庫的超詳細(xì)教程

    java連接SQL?Server數(shù)據(jù)庫的超詳細(xì)教程

    最近在java連接SQL數(shù)據(jù)庫時(shí)會(huì)出現(xiàn)一些問題,所以這篇文章主要給大家介紹了關(guān)于java連接SQL?Server數(shù)據(jù)庫的超詳細(xì)教程,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • PowerJobAutoConfiguration自動(dòng)配置源碼流程解析

    PowerJobAutoConfiguration自動(dòng)配置源碼流程解析

    這篇文章主要為大家介紹了PowerJobAutoConfiguration自動(dòng)配置源碼流程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-12-12
  • Spring boot GC實(shí)現(xiàn)過程原理解析

    Spring boot GC實(shí)現(xiàn)過程原理解析

    這篇文章主要介紹了Spring boot GC實(shí)現(xiàn)過程原理解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 基于@RequestMapping 用法詳解之地址映射

    基于@RequestMapping 用法詳解之地址映射

    這篇文章主要介紹了@RequestMapping 用法詳解之地址映射,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Spring Boot整合消息隊(duì)列RabbitMQ的實(shí)現(xiàn)示例

    Spring Boot整合消息隊(duì)列RabbitMQ的實(shí)現(xiàn)示例

    本文主要介紹了Spring Boot整合消息隊(duì)列RabbitMQ的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • Java項(xiàng)目中如何訪問WEB-INF下jsp頁面

    Java項(xiàng)目中如何訪問WEB-INF下jsp頁面

    這篇文章主要介紹了Java項(xiàng)目中如何訪問WEB-INF下jsp頁面,文章通過示例代碼和圖文解析介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Spring OAuth2.0 單元測(cè)試解決方案

    Spring OAuth2.0 單元測(cè)試解決方案

    這篇文章主要介紹了Spring OAuth2.0 單元測(cè)試解決方案,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • JavaMe開發(fā)繪制可自動(dòng)換行文本

    JavaMe開發(fā)繪制可自動(dòng)換行文本

    JavaMe Graphics類中的drawString不支持文本換行,這樣繪制比較長的字符串時(shí),文本被繪制在同一行,超過屏幕部分的字符串被截?cái)嗔?。如何使繪制的文本能自動(dòng)換行呢?
    2015-09-09

最新評(píng)論

太原市| 喜德县| 阿鲁科尔沁旗| 理塘县| 安陆市| 苏尼特右旗| 甘德县| 肥西县| 甘南县| 泾源县| 栾川县| 新巴尔虎左旗| 湘潭市| 沿河| 松滋市| 鄂托克旗| 根河市| 莆田市| 太仓市| 阳城县| 平远县| 石嘴山市| 尚志市| 八宿县| 嘉定区| 桦甸市| 麦盖提县| 蒲江县| 利辛县| 阿坝县| 望城县| 成都市| 台南市| 呼伦贝尔市| 时尚| 徐州市| 高阳县| 林甸县| 耿马| 九寨沟县| 石狮市|