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

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

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

線程狀態(tài)

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

創(chuàng)建線程

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

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

1.創(chuàng)建一個(gè)Thread類的子類 class MyThread extends Thread
2.在Thread類的子類中重寫(xiě)Thread類中的run()方法
3.創(chuàng)建Thread類的子類對(duì)象 MyThread t1 = new MyThread();
4.調(diào)用Thread類中的方法start()方法,開(kāi)啟新的線程,執(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接口[無(wú)入?yún)?,無(wú)返回值]

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

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

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

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

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

5.調(diào)用Thread類中的start方法,開(kāi)啟新的線程執(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接口[無(wú)入?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線程啟動(dòng),與main線程互不干擾
        while (!futureTask.isDone()) {
        }
        // 3、獲得返回值:get方法盡量放在后面,一旦調(diào)用,線程等待等到執(zhí)行完畢,會(huì)導(dǎo)致堵塞
        String value = futureTask.get();
        System.out.println("MyData的返回值:" + value);
    }
}

通過(guò)線程池方式

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

通過(guò)lambda表達(dá)式

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

線程同步

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

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

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

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

package thread;
/*
 * 兩個(gè)線依次次輸出1 2 3 4
 */
public class ThreadSyncTest2 {
    // 使用專用鎖對(duì)象(不可變)
    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;
/*
 * 兩個(gè)線程一次輸出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存在的問(wèn)題

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

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

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

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

相關(guān)文章

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

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

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

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

    Java代理分為靜態(tài)代理和動(dòng)態(tài)代理,靜態(tài)代理需手動(dòng)編寫(xiě)代理類,適合少量對(duì)象,動(dòng)態(tài)代理運(yùn)行時(shí)自動(dòng)生成代理類,適用于大量對(duì)象,如Spring AOP,這篇文章主要介紹了Java代理模式之靜態(tài)代理與動(dòng)態(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ǔ)到高級(jí),涵蓋了各種常見(jiàn)場(chǎng)景和最佳實(shí)踐,通過(guò)本教程,讀者可以理解RestClient的核心概念和優(yōu)勢(shì),感興趣的朋友跟隨小編一起看看吧
    2026-01-01
  • java springmvc 注冊(cè)中央調(diào)度器代碼解析

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

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

    java的nio的使用示例分享

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

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

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

    JavaSE遞歸求解漢諾塔問(wèn)題的思路與方法

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

    解決idea找不到setting.xml文件的問(wèn)題

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

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

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

最新評(píng)論

北流市| 龙陵县| 鄂托克前旗| 延吉市| 图片| 赤水市| 中西区| 高邮市| 潼南县| 墨江| 奉化市| 广水市| 静乐县| 霍山县| 璧山县| 高青县| 信阳市| 天柱县| 弥渡县| 全州县| 峨眉山市| 卢龙县| 铁岭县| 佳木斯市| 隆昌县| 宁蒗| 太白县| 西畴县| 舒兰市| 扎囊县| 灵山县| 寿光市| 长春市| 红原县| 曲阜市| 丰县| 崇信县| 莱阳市| 托克逊县| 浦县| 公主岭市|