使用Condition實現多線程之間調用(生產消費模式)

来源:http://www.cnblogs.com/tankaixiong/archive/2016/11/23/6093779.html
-Advertisement-
Play Games

一,object 類的wait(),notify()和notifyAll() Java 線程類也是一個object 類,它的實例都繼承自java.lang.Thread 或其子類。wait(),notify()和notifyAll()是Object類中的方法,常用於線程之間調度。 線程無數據運行可調 ...


一,object 類的wait(),notify()和notifyAll()

Java 線程類也是一個object 類,它的實例都繼承自java.lang.Thread 或其子類。
wait(),notify()和notifyAll()是Object類中的方法,常用於線程之間調度。

線程無數據運行可調用wait()讓線程等待,不占用CUP資源,提高CPU有效的利用率。
例如,線程 B 可以等待線程 A 的一個信號,這個信號會通知線程 B 數據已經準備好了,B可以執行業務邏輯。

線程之間調度常應用於生產與消費模式下。

利用Object 對象的wait(),notify()和notifyAll()可以實現,但JDK1.5後有更好的替代方法。

二,Condition 類增強類


Condition 類,實現線程間的協作,相比使用Object的wait()、notify(),使用Condition的await()、signal()這種方式實現線程間協作更加安全和高效。因此通常來說比較推薦使用Condition。

Condition依賴於Lock介面,生成一個Condition的基本代碼是lock.newCondition()
調用Condition的await()和signal()方法,必須在lock.lock()和lock.unlock之間才可以使用

 

三,Object與Conditon 對比

  Conditon中的await()對應Object的wait();
  Condition中的signal()對應Object的notify();
  Condition中的signalAll()對應Object的notifyAll()。

 

 四,使用Condition 實現生產消費

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by tank  on 2016/11/22.
 * 使用Condition 實現線程間生產消費模式
 */
public class ConditionDemo {

    Object[] queue = new Object[100];//隊列
    int readIndex = 0;//read索引位置
    int writeIndex = 0;
    int dataLen = 0;

    final Lock lock = new ReentrantLock();

    final Condition fullCondition = lock.newCondition();
    final Condition emptyCondition = lock.newCondition();

    public static void main(String[] args) {
        final ConditionDemo demo = new ConditionDemo();


        new Thread() {
            @Override
            public void run() {
                for (int i = 0; i < 1000; i++) {
                    demo.write(i);
                }
            }
        }.start();

        new Thread() {
            @Override
            public void run() {
                while (true) {
                    Object obj = demo.read();
                    if (obj != null) {
                        System.out.println((Integer) obj);
                    }

                }
            }
        }.start();

    }

    //生產
    public void write(Object obj) {
        lock.lock();

        try {

            if (dataLen >= queue.length) {//隊列寫滿了
                System.out.println("隊列寫滿了,等待.....");
                fullCondition.await();
                System.out.println("隊列有空位了,喚醒.....");

            }

            queue[writeIndex] = obj;

            writeIndex++;
            dataLen++;

            if (writeIndex >= queue.length) {
                writeIndex = 0;
            }

            emptyCondition.signal();


        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    //消費
    public Object read() {
        lock.lock();

        try {
            if (dataLen <= 0) {
                System.out.println("隊列空了,等待數據.....");
                emptyCondition.await();
                System.out.println("隊列有數據了,喚醒.....");
            }

            Object obj = queue[readIndex];

            readIndex++;
            dataLen--;

            if (readIndex >= queue.length) {
                readIndex = 0;
            }

            fullCondition.signal();

            return obj;


        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return null;
    }
}

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • .NET框架下最全面的報表解決方案,支持多種報表導出格式,擁有簡單且強大的報表引擎。本系列教程適合Stimulsoft Reports上手入門。 ...
  • 上個項目中用到了上傳視頻,本來打算用百度的webuploader做的,但是webuploader可能有個毛病就是不能上傳太大的東西。 於是乎,只能換個方法做了啊,看了半天最終決定用傳統的uploaderfile來做。順便吐槽下uploaderfile真的是,和webuploader相比完全是有點複雜 ...
  • 進程:運行應用程式實例 線程:對CPU進行虛擬化。windows為每個進程都提供了該進程專用的線程,這樣當一個進程“假死”,不會影響到其他進程。 線程開銷 線程可以使windows在長時間運行任務可以隨時得到響應,允許用戶使用一個應用程式將已凍結的應用程式強制結束。 線程內核對象(thread ke ...
  • 效果圖: style: xaml.CS: Loaded: emoticons.xml: <?xml version="1.0"?><Emoticons> <Emoticon id="0" tip="微笑">0.gif</Emoticon> <Emoticon id="1" tip="撇嘴">1.gi ...
  • 談及到C#的基本特性,“委托”是不得不去瞭解和深入分析的一個特性。對於大多數剛入門的程式員談到“委托”時,都會想到“將方法作為方法的參數進行傳遞”,很多時候都只是知道簡單的定義,主要是因為“委托”在理解上有較其他特性比較難的地方。在本次說明中,不會將委托的簡單聲明和調用作為重點。 “委托”不需要直接 ...
  • 面向對象的概念 :指以對象的方式來思考問題,在抽象對象的時候,值關心我們關註的點,忽略我們不關註的點 在面向對象中有兩個非常重要的元素:類(Class)和對象(object) 類:類是一個抽象的概念,是一個廣泛的值 對象:具體的個體 類裡面的元素(person):屬性(attribute):描述一類 ...
  • function get_mobile_area($mobile){ header('Content-Type:text/html;charset=gbk'); $url = 'http://life.tenpay.com/cgi-bin/mobile/MobileQueryAttribution. ...
  • WeekCalendarUtils工具類代碼,傳入起始日期即可返回對應日期的周歷日曆,年月部分添加周數統計 一個table頁面展示部分 1 <style type="text/css"> 2 td { 3 border: 1px solid black; 4 background-color: #e ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...