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

Java三大線程同步機(jī)制代碼實(shí)戰(zhàn)指南

 更新時間:2026年03月07日 10:21:00   作者:程序員碼小跳  
文章介紹了Java線程的五種狀態(tài)(新建、就緒、運(yùn)行、阻塞、死亡),以及線程的創(chuàng)建方式(繼承Thread類、實(shí)現(xiàn)Runnable接口、實(shí)現(xiàn)Callable接口),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧

線程狀態(tài)

  • 新建(New):當(dāng)程序使用 new 關(guān)鍵字、Thread 類或其子類建立一個線程對象后,該線程就處于新建狀態(tài)。它保持這個狀態(tài)直到程序 start() 這個線程。(new MyThread)
  • 就緒(Runnable 或Ready to Run):當(dāng)線程對象調(diào)用了start()方法之后,該線程處于就緒狀態(tài)。就緒狀態(tài)的線程處于就緒隊(duì)列中,要等待JVM里線程調(diào)度器的調(diào)度。(new MyThread.start() )
  • 運(yùn)行(Running):如果處于就緒狀態(tài)的線程獲得了 CPU,開始執(zhí)行 run()方法的線程執(zhí)行體,則該線程處于運(yùn)行狀態(tài)。
  • 阻塞 (Blocked):如果一個線程執(zhí)行了sleep、suspend等方法,失去CPU所占用資源之后,該線程就從運(yùn)行狀態(tài)進(jìn)入阻塞狀態(tài)。在睡眠時間已到或獲得設(shè)備資源后可以重新進(jìn)入就緒狀態(tài)。
  • 死亡(Dead):線程會以下面三種方式結(jié)束,結(jié)束后就是死亡狀態(tài)。
    • 正常結(jié)束:run()或 call()方法執(zhí)行完成,線程正常結(jié)束。
    • 異常結(jié)束:線程拋出一個未捕獲的 Exception 或 Error。
    • 調(diào)用結(jié)束:直接調(diào)用該線程的 stop()方法來結(jié)束該線程—該方法通常容易導(dǎo)致死鎖,不推薦使用

創(chuàng)建線程

繼承Thread類[無入?yún)?、無返回值]

實(shí)現(xiàn)步驟:

1.創(chuàng)建一個Thread類的子類 class MyThread extends Thread
2.在Thread類的子類中重寫Thread類中的run()方法
3.創(chuàng)建Thread類的子類對象 MyThread t1 = new MyThread();
4.調(diào)用Thread類中的方法start()方法,開啟新的線程,執(zhí)行run方法 t1.start()
class MyThread extends Thread {
    @Override
    public void run() {
    }
}
public class demo21Thread01 {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        t1.start();
    }
}

實(shí)現(xiàn)Runnable接口[無入?yún)?,無返回值]

實(shí)現(xiàn)步驟:

1.創(chuàng)建一個Runnable接口的實(shí)現(xiàn)類 class myThread implements Runnable

2.在實(shí)現(xiàn)類中重寫Runnable接口的run方法

3.創(chuàng)建一個Runnable接口的實(shí)現(xiàn)類對象 myThread t1 = new myThread();

4.創(chuàng)建Thread類對象,構(gòu)造方法中傳遞Runnable接口的實(shí)現(xiàn)類對象Thread t=new Thread(t1);

5.調(diào)用Thread類中的start方法,開啟新的線程執(zhí)行run方法 t.start()

class myThread02 implements Runnable {
    public void run() {
    }
}
public class demo21Thread01 {
    public static void main(String args[]) throws InterruptedException {
        myThread02 mythread = new myThread02();
        Thread t = new Thread(mythread);
        t.start();
    }
}

實(shí)現(xiàn)Callable接口[無入?yún)ⅲ蟹祷刂礭

class MyTask implements Callable<String> {
    @Override
    public String call() throws Exception {
        try {
            // 模擬業(yè)務(wù)處理
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "success";
    }
}
public class demo21Thread01 {
    public static void main(String[] args) throws Exception {
        // 1、callable怎么用,引入FutureTask初始化
        FutureTask<String> futureTask = new FutureTask<>(new MyTask());
        new Thread(futureTask).start();
        // 2、FutureTask線程啟動,與main線程互不干擾
        while (!futureTask.isDone()) {
        }
        // 3、獲得返回值:get方法盡量放在后面,一旦調(diào)用,線程等待等到執(zhí)行完畢,會導(dǎo)致堵塞
        String value = futureTask.get();
        System.out.println("MyData的返回值:" + value);
    }
}

通過線程池方式

ExecutorService es= Executors.newCachedThreadPool();		//緩存型線程池
ExecutorService es= Executors.newFixedThreadPool(2);		//固定型線程池
ExecutorService es=Executors.newSingleThreadExecutor();  	//單線程型線程池
以上三種通過es.submit(new MyRunable03(i));提交任務(wù)
ScheduledExecutorService es = Executors.newScheduledThreadPool(3);//延遲執(zhí)行或重復(fù)執(zhí)行型線程池
通過es.schedule(new myRunnable(i), 2, TimeUnit.SECONDS);提交任務(wù)

通過lambda表達(dá)式

new Thread(() -> {
    System.out.println("程序已啟動");
}).start();

線程同步

3種讓線程等待和喚醒的方法

方式1: Object中的wait()線程等待、notify()喚醒線程【PS:必須配合synchronized】

方式2: Condition的await()線程等待、signal()喚醒線程【PS:必須配合ReentrantLock】

方式3: LockSupport的park()線程等待、unpark()喚醒線程

package thread;
/*
 * 兩個線依次次輸出1 2 3 4
 */
public class ThreadSyncTest2 {
    // 使用專用鎖對象(不可變)
    private static Object LOCK = new Object();
    private static int num = 1;
    public static void main(String[] args) {
        new Thread(() -> {
            while (num <= 10) {
                try {
                    synchronized (LOCK) {
                        if (num % 2 == 0) {
                            System.out.println("偶數(shù)線程A: " + num++);
                            LOCK.notify();
                        } else {
                            LOCK.wait();
                        }
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }, "偶數(shù)線程A").start();
        new Thread(() -> {
            while (num <= 10) {
                try {
                    synchronized (LOCK) {
                        if (num % 2 == 1) {
                            System.out.println("基數(shù)線程B: " + num++);
                            LOCK.notify();
                        } else {
                            LOCK.wait();
                        }
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        }, "基數(shù)線程B").start();
    }
}
package thread;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
/*
 * 兩個線程一次輸出1 2 3 4
 */
public class ThreadSyncTest3 {
    private static int num = 1;
    // 鎖與條件變量
    private static final ReentrantLock LOCK = new ReentrantLock();
    private static final Condition ODD_COND = LOCK.newCondition();    // 奇數(shù)條件隊(duì)列
    private static final Condition EVEN_COND = LOCK.newCondition();    // 偶數(shù)條件隊(duì)列
    public static void main(String[] args) {
        new Thread(() -> {
            while (num <= 10) {
                LOCK.lock();
                try {
                    if (num % 2 == 0) {
                        System.out.println("偶數(shù)線程A: " + num++);
                        ODD_COND.signal();
                    } else {
                        EVEN_COND.await();
                    }
                } catch (InterruptedException e) {
                    break;
                } finally {
                    LOCK.unlock();
                }
            }
            EVEN_COND.signal();
        }, "偶數(shù)線程A").start();
        new Thread(() -> {
            while (num <= 10) {
                LOCK.lock();
                try {
                    if (num % 2 == 1) {
                        System.out.println("基數(shù)線程B: " + num++);
                        EVEN_COND.signal();
                    } else {
                        ODD_COND.await();
                    }
                } catch (InterruptedException e) {
                    break;
                } finally {
                    LOCK.unlock();
                }
            }
            EVEN_COND.signal();
        }, "基數(shù)線程B").start();
    }
}

方式1和方式2存在的問題

1、線程先要獲得并持有鎖,必須在鎖塊(synchronized或lock)中,必須配合使用

2、必須要先等待后喚醒,線程才能夠被喚醒

LockSupport主要是解決上面2個問題,LockSupport 類使用了一種名為 permit(許可)的概念來做到阻塞和喚醒線程的功能,每個線程都有一個許可(permit),permit 只有兩個值 1 和零,默認(rèn)是零,不能累積

到此這篇關(guān)于Java三大線程同步機(jī)制代碼實(shí)戰(zhàn)指南的文章就介紹到這了,更多相關(guān)java線程同步機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • springboot責(zé)任鏈模式實(shí)現(xiàn)多級校驗(yàn)

    springboot責(zé)任鏈模式實(shí)現(xiàn)多級校驗(yàn)

    責(zé)任鏈模式是將鏈中的每一個節(jié)點(diǎn)看作是一個對象,每個節(jié)點(diǎn)處理的請求不同,且內(nèi)部自動維護(hù)一個下一節(jié)點(diǎn)對象,下面我們來聊聊springboot如何利用責(zé)任鏈模式實(shí)現(xiàn)多級校驗(yàn)吧
    2024-11-11
  • Java代理模式之靜態(tài)代理與動態(tài)代理詳解

    Java代理模式之靜態(tài)代理與動態(tài)代理詳解

    Java代理分為靜態(tài)代理和動態(tài)代理,靜態(tài)代理需手動編寫代理類,適合少量對象,動態(tài)代理運(yùn)行時自動生成代理類,適用于大量對象,如Spring AOP,這篇文章主要介紹了Java代理模式之靜態(tài)代理與動態(tài)代理的相關(guān)資料,需要的朋友可以參考下
    2026-01-01
  • Spring Boot 3 RestClient使用實(shí)戰(zhàn)案例

    Spring Boot 3 RestClient使用實(shí)戰(zhàn)案例

    本文詳細(xì)介紹了SpringBoot3中RestClient的使用方法,從基礎(chǔ)到高級,涵蓋了各種常見場景和最佳實(shí)踐,通過本教程,讀者可以理解RestClient的核心概念和優(yōu)勢,感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • java springmvc 注冊中央調(diào)度器代碼解析

    java springmvc 注冊中央調(diào)度器代碼解析

    這篇文章主要介紹了java springmvc 注冊中央調(diào)度器代碼解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-08-08
  • java的nio的使用示例分享

    java的nio的使用示例分享

    這篇教程展示了5個在Java編程的一些常見場景里使用NIO和NIO.2包的簡單示例,需要的朋友可以參考下
    2014-03-03
  • java逐行讀取文件(讀取文件每一行、按行讀取文件)附帶詳細(xì)代碼

    java逐行讀取文件(讀取文件每一行、按行讀取文件)附帶詳細(xì)代碼

    這篇文章主要給大家介紹了關(guān)于java逐行讀取文件(讀取文件每一行、按行讀取文件)的相關(guān)資料,讀取文件是我們在日常工作中經(jīng)常遇到的一個需求,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-09-09
  • JavaSE遞歸求解漢諾塔問題的思路與方法

    JavaSE遞歸求解漢諾塔問題的思路與方法

    遞歸是一種非常重要的算法思想,無論你是前端開發(fā),還是后端開發(fā),都需要掌握它,下面這篇文章主要給給大家介紹了關(guān)于JavaSE遞歸求解漢諾塔問題的思路與方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • 解決idea找不到setting.xml文件的問題

    解決idea找不到setting.xml文件的問題

    這篇文章主要介紹了解決idea找不到setting.xml文件的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 使用Java和SpringBoot實(shí)現(xiàn)服務(wù)器發(fā)送事件(Server-Sent Events)

    使用Java和SpringBoot實(shí)現(xiàn)服務(wù)器發(fā)送事件(Server-Sent Events)

    使用Java開發(fā)web應(yīng)用,大多數(shù)時候我們提供的接口返回數(shù)據(jù)都是一次性完整返回,有些時候,我們也需要提供流式接口持續(xù)寫出數(shù)據(jù),以下提供一種簡單的方式,本文給大家介紹了如何在Java web中實(shí)現(xiàn)服務(wù)器發(fā)送事件,需要的朋友可以參考下
    2024-02-02

最新評論

将乐县| 特克斯县| 铁岭市| 曲周县| 溧水县| 沂源县| 吴桥县| 峨边| 苏州市| 星座| 左贡县| 宜宾县| 伊通| 罗甸县| 秦皇岛市| 武功县| 彩票| 永胜县| 金塔县| 建宁县| 长子县| 梁山县| 石阡县| 丁青县| 游戏| 松滋市| 吴堡县| 崇文区| 宜丰县| 小金县| 衢州市| 思茅市| 古田县| 宁德市| 苏尼特左旗| 静乐县| 文成县| 彭阳县| 年辖:市辖区| 嘉兴市| 越西县|