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

Java線程之間通信的幾種方式詳解

 更新時(shí)間:2025年03月21日 11:08:37   作者:yymagicer  
在 Java 中,線程之間的通信是通過(guò)共享內(nèi)存模型來(lái)實(shí)現(xiàn)的,線程通過(guò)共享的對(duì)象和變量來(lái)交換數(shù)據(jù),為了確保線程間通信的正確性,Java 提供了一系列機(jī)制來(lái)實(shí)現(xiàn)線程安全、同步和通信,以下是常用的幾種線程間通信的方式,以及它們的使用方法和場(chǎng)景,需要的朋友可以參考下

1. 共享變量與同步機(jī)制

多個(gè)線程可以通過(guò)共享對(duì)象的變量進(jìn)行通信,但為了避免數(shù)據(jù)不一致的問(wèn)題,必須使用同步機(jī)制來(lái)控制對(duì)共享變量的訪問(wèn)。

  • 使用 synchronized 關(guān)鍵字: synchronized 確保在同一時(shí)刻只有一個(gè)線程可以執(zhí)行同步代碼塊。它可以同步方法或代碼塊,用于保護(hù)共享數(shù)據(jù)。

    示例:

class Counter {
    private int count = 0;
 
    public synchronized void increment() {
        count++;
    }
 
    public synchronized int getCount() {
        return count;
    }
}
 
public class SyncExample {
    public static void main(String[] args) {
        Counter counter = new Counter();
 
        Thread t1 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
 
        Thread t2 = new Thread(() -> {
            for (int i = 0; i < 1000; i++) {
                counter.increment();
            }
        });
 
        t1.start();
        t2.start();
 
        try {
            t1.join();
            t2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
 
        System.out.println("Final count: " + counter.getCount());
    }
}
  • 使用場(chǎng)景:用于保護(hù)共享資源,防止多個(gè)線程同時(shí)讀寫導(dǎo)致數(shù)據(jù)不一致的問(wèn)題。

  • 使用 volatile 關(guān)鍵字: volatile 確保一個(gè)線程對(duì)變量的修改對(duì)其他線程立即可見(jiàn)。它適用于輕量級(jí)的變量同步,通常用于標(biāo)志位控制。

    示例:

class Flag {
    private volatile boolean running = true;
 
    public void stop() {
        running = false;
    }
 
    public boolean isRunning() {
        return running;
    }
}
 
public class VolatileExample {
    public static void main(String[] args) {
        Flag flag = new Flag();
 
        Thread t1 = new Thread(() -> {
            while (flag.isRunning()) {
                System.out.println("Thread is running");
            }
            System.out.println("Thread stopped");
        });
 
        t1.start();
 
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
 
        flag.stop();
    }
}
  • 使用場(chǎng)景:用于控制線程的退出、開關(guān)操作等輕量級(jí)場(chǎng)景。

2. wait()、notify() 和 notifyAll()

Object 類的這三個(gè)方法用于在同步塊內(nèi)實(shí)現(xiàn)線程間的協(xié)作。線程可以通過(guò) wait() 進(jìn)入等待狀態(tài),直到另一個(gè)線程調(diào)用 notify() 或 notifyAll() 喚醒它們。

  • wait():當(dāng)前線程進(jìn)入等待狀態(tài),并釋放鎖。
  • notify():?jiǎn)拘岩粋€(gè)正在等待同一鎖的線程。
  • notifyAll():?jiǎn)拘阉械却绘i的線程。

示例:生產(chǎn)者-消費(fèi)者模型

class SharedResource {
    private int value;
    private boolean hasValue = false;
 
    public synchronized void produce(int newValue) throws InterruptedException {
        while (hasValue) {
            wait(); // 等待消費(fèi)者消費(fèi)
        }
        value = newValue;
        hasValue = true;
        System.out.println("Produced: " + value);
        notify(); // 喚醒消費(fèi)者
    }
 
    public synchronized void consume() throws InterruptedException {
        while (!hasValue) {
            wait(); // 等待生產(chǎn)者生產(chǎn)
        }
        System.out.println("Consumed: " + value);
        hasValue = false;
        notify(); // 喚醒生產(chǎn)者
    }
}
 
public class ProducerConsumerExample {
    public static void main(String[] args) {
        SharedResource resource = new SharedResource();
 
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    resource.produce(i);
                    Thread.sleep(100);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 5; i++) {
                    resource.consume();
                    Thread.sleep(200);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        producer.start();
        consumer.start();
    }
}

使用場(chǎng)景:適用于線程間的協(xié)調(diào)工作,比如生產(chǎn)者-消費(fèi)者模型,一個(gè)線程負(fù)責(zé)生產(chǎn)資源,另一個(gè)線程負(fù)責(zé)消費(fèi)資源。

3. Lock 和 Condition 接口

相比 synchronized,Lock 提供了更靈活的同步機(jī)制,而 Condition 可以替代 wait()、notify() 和 notifyAll(),并支持多個(gè)等待條件。

  • ReentrantLock:常用于顯式鎖控制,可以提供公平鎖機(jī)制(按獲取鎖的順序進(jìn)行調(diào)度)。
  • Condition:類似于 Object 的 wait()、notify(),可以創(chuàng)建多個(gè) Condition 來(lái)進(jìn)行復(fù)雜的線程協(xié)調(diào)。

示例:

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
 
class BoundedBuffer {
    private final int[] buffer;
    private int count, in, out;
    private final Lock lock = new ReentrantLock();
    private final Condition notFull = lock.newCondition();
    private final Condition notEmpty = lock.newCondition();
 
    public BoundedBuffer(int size) {
        buffer = new int[size];
    }
 
    public void put(int value) throws InterruptedException {
        lock.lock();
        try {
            while (count == buffer.length) {
                notFull.await(); // 等待緩沖區(qū)未滿
            }
            buffer[in] = value;
            in = (in + 1) % buffer.length;
            count++;
            notEmpty.signal(); // 喚醒消費(fèi)線程
        } finally {
            lock.unlock();
        }
    }
 
    public int take() throws InterruptedException {
        lock.lock();
        try {
            while (count == 0) {
                notEmpty.await(); // 等待緩沖區(qū)非空
            }
            int value = buffer[out];
            out = (out + 1) % buffer.length;
            count--;
            notFull.signal(); // 喚醒生產(chǎn)線程
            return value;
        } finally {
            lock.unlock();
        }
    }
}
 
public class LockConditionExample {
    public static void main(String[] args) {
        BoundedBuffer buffer = new BoundedBuffer(5);
 
        Thread producer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    buffer.put(i);
                    System.out.println("Produced: " + i);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        Thread consumer = new Thread(() -> {
            try {
                for (int i = 0; i < 10; i++) {
                    int value = buffer.take();
                    System.out.println("Consumed: " + value);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });
 
        producer.start();
        consumer.start();
    }
}

使用場(chǎng)景:適用于需要顯式鎖定、更復(fù)雜的條件等待場(chǎng)景,比如多條件同步、多生產(chǎn)者-消費(fèi)者模型。

4. java.util.concurrent 包的并發(fā)工具

Java 提供了 java.util.concurrent 包下的一系列高級(jí)并發(fā)工具類來(lái)簡(jiǎn)化線程間通信。

  • BlockingQueue:線程安全的隊(duì)列,常用于生產(chǎn)者-消費(fèi)者模式。
  • CountDownLatch:允許一個(gè)或多個(gè)線程等待其他線程完成某些操作。
  • CyclicBarrier:多個(gè)線程在某個(gè)點(diǎn)上相互等待,直到所有線程到達(dá)該點(diǎn)。
  • Semaphore:用于控制對(duì)資源的訪問(wèn)許可。
  • Exchanger:用于兩個(gè)線程之間交換數(shù)據(jù)。

到此這篇關(guān)于Java線程之間通信的幾種方式詳解的文章就介紹到這了,更多相關(guān)Java線程之間通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java時(shí)間戳與日期相互轉(zhuǎn)換工具詳解

    java時(shí)間戳與日期相互轉(zhuǎn)換工具詳解

    這篇文章主要為大家詳細(xì)介紹了java各種時(shí)間戳與日期之間相互轉(zhuǎn)換的工具,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-12-12
  • MyBatis-Plus多表關(guān)聯(lián)分頁(yè)方式

    MyBatis-Plus多表關(guān)聯(lián)分頁(yè)方式

    文章介紹了使用MyBatis-Plus的QueryWrapper進(jìn)行多表關(guān)聯(lián)查詢的方法,通過(guò)select()方法定義需要的字段,將ID字段轉(zhuǎn)化為名稱字段,實(shí)現(xiàn)一次查詢,這種方法簡(jiǎn)單便捷,但在使用where語(yǔ)句查詢子表字段時(shí)有一定限制,作者建議建立數(shù)據(jù)庫(kù)視圖表作為更好的解決方案
    2026-05-05
  • Jmeter的接口測(cè)試詳細(xì)步驟并實(shí)現(xiàn)業(yè)務(wù)閉環(huán)

    Jmeter的接口測(cè)試詳細(xì)步驟并實(shí)現(xiàn)業(yè)務(wù)閉環(huán)

    這篇文章主要介紹了Jmeter的接口測(cè)試詳細(xì)步驟并實(shí)現(xiàn)業(yè)務(wù)閉環(huán),文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • 解決Java J2EE亂碼問(wèn)題的方法

    解決Java J2EE亂碼問(wèn)題的方法

    這篇文章主要為大家詳細(xì)介紹了解決Java J2EE亂碼問(wèn)題的方法的相關(guān)資料,需要的朋友可以參考下
    2016-04-04
  • Java日志API管理最佳實(shí)踐詳解

    Java日志API管理最佳實(shí)踐詳解

    這篇文章主要介紹了Java日志API管理最佳實(shí)踐詳解,記錄日志只是有效地利用日志的第一步,更重要的是如何對(duì)程序運(yùn)行時(shí)產(chǎn)生的日志進(jìn)行處理和分析。,需要的朋友可以參考下
    2019-06-06
  • Java深入講解Object類常用方法的使用

    Java深入講解Object類常用方法的使用

    前面java繼承中說(shuō)到的Object類是java中一個(gè)特殊的類,所有的類都是直接或者間接的繼承自O(shè)bject類,即如果某個(gè)類沒(méi)有使用extends關(guān)鍵字則默認(rèn)是java.lang.Object類的子類,所以所有的類都可以使用Object類中定義的方法,下面介紹Object類的常用方法
    2022-04-04
  • spring啟動(dòng)后保證創(chuàng)建的對(duì)象不被垃圾回收器回收

    spring啟動(dòng)后保證創(chuàng)建的對(duì)象不被垃圾回收器回收

    最近看到一個(gè)問(wèn)題是,spring在啟動(dòng)后如何保證創(chuàng)建的對(duì)象不被垃圾回收器回收?。所以本文結(jié)合jvm的垃圾回收機(jī)制和spring中的源代碼做出自己的一點(diǎn)猜測(cè)。有需要的朋友們可以參考借鑒。
    2016-09-09
  • Java多線程實(shí)現(xiàn)之Callable詳解

    Java多線程實(shí)現(xiàn)之Callable詳解

    這篇文章主要介紹了Java多線程實(shí)現(xiàn)之Callable詳解,Callable是一個(gè)接口,用于實(shí)現(xiàn)多線程,與實(shí)現(xiàn)Runnable類似,但是功能更強(qiáng)大,通過(guò)實(shí)現(xiàn)Callable接口,我們需要重寫call()方法,該方法可以在任務(wù)結(jié)束后提供一個(gè)返回值,需要的朋友可以參考下
    2023-08-08
  • springboot websocket簡(jiǎn)單入門示例

    springboot websocket簡(jiǎn)單入門示例

    這篇文章主要介紹了springboot websocket簡(jiǎn)單入門示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-08-08
  • Springboot 全局時(shí)間格式化三種方式示例詳解

    Springboot 全局時(shí)間格式化三種方式示例詳解

    時(shí)間格式化在項(xiàng)目中使用頻率是非常高的,當(dāng)我們的 API? 接口返回結(jié)果,需要對(duì)其中某一個(gè) date? 字段屬性進(jìn)行特殊的格式化處理,通常會(huì)用到 SimpleDateFormat? 工具處理,這篇文章主要介紹了3 種 Springboot 全局時(shí)間格式化方式,需要的朋友可以參考下
    2024-01-01

最新評(píng)論

拉萨市| 大冶市| 景德镇市| 库车县| 正镶白旗| 新丰县| 金华市| 崇明县| 涿州市| 平利县| 平乐县| 宝应县| 新巴尔虎左旗| 吉木萨尔县| 三门县| 榆社县| 开远市| 石城县| 阿合奇县| 都安| 宜川县| 婺源县| 申扎县| 漠河县| 贡觉县| 井陉县| 巨野县| 萨嘎县| 铁岭县| 柳州市| 健康| 五指山市| 玛多县| 鹤峰县| 五台县| 贵溪市| 凭祥市| 日土县| 深州市| 松阳县| 嵊泗县|