java線程通信,java線程通信機制

本文目錄一覽:

JAVA線程間通信的幾種方式

Java多線程間的通信

Java還提供了一種線程間通信的機制,這種通信通什麼實現?

wait,notify等機制

或使用pipeInputStream和pipeOutputStream

1. 線程的幾種狀態

線程有四種狀態,任何一個線程肯定處於這四種狀態中的一種:

1) 產生(New):線程對象已經產生,但尚未被啟動,所以無法執行。如通過new產生了一個線程對象後沒對它調用start()函數之前。

2) 可執行(Runnable):每個支持多線程的系統都有一個排程器,排程器會從線程池中選擇一個線程並啟動它。當一個線程處於可執行狀態時,表示它可能正處於線程池中等待排排程器啟動它;也可能它已正在執行。如執行了一個線程對象的start()方法後,線程就處於可執行狀態,但顯而易見的是此時線程不一定正在執行中。

3) 死亡(Dead):當一個線程正常結束,它便處於死亡狀態。如一個線程的run()函數執行完畢後線程就進入死亡狀態。

4) 停滯(Blocked):當一個線程處於停滯狀態時,系統排程器就會忽略它,不對它進行排程。

如何在學習Java過程中實現線程之間的通信

在java中,每個對象都有兩個池,鎖池(monitor)和等待池(waitset),每個對象又都有wait、notify、notifyAll方法,使用它們可以實現線程之間的通信,只是平時用的較少.

wait(): 使當前線程處於等待狀態,直到另外的線程調用notify或notifyAll將它喚醒

notify(): 喚醒該對象監聽的其中一個線程(規則取決於JVM廠商,FILO,FIFO,隨機…)

notifyAll(): 喚醒該對象監聽的所有線程

鎖池: 假設T1線程已經擁有了某個對象(注意:不是類)的鎖,而其它的線程想要調用該對象的synchronized方法(或者synchronized塊),由於這些線程在進入對象的synchronized方法之前都需要先獲得該對象的鎖的擁有權,但是該對象的鎖目前正被T1線程擁有,所以這些線程就進入了該對象的鎖池中.

等待池: 假設T1線程調用了某個對象的wait()方法,T1線程就會釋放該對象的鎖(因為wait()方法必須出現在synchronized中,這樣自然在執行wait()方法之前T1線程就已經擁有了該對象的鎖),同時T1線程進入到了該對象的等待池中.如果有其它線程調用了相同對象的notifyAll()方法,那麼處於該對象的等待池中的線程就會全部進入該對象的鎖池中,從新爭奪鎖的擁有權.如果另外的一個線程調用了相同對象的notify()方法,那麼僅僅有一個處於該對象的等待池中的線程(隨機)會進入該對象的鎖池.

java實現線程間通信的四種方式

1、synchronized同步:這種方式,本質上就是“共享內存”式的通信。多個線程需要訪問同一個共享變量,誰拿到了鎖(獲得了訪問權限),誰就可以執行。

2、while輪詢:其實就是多線程同時執行,會犧牲部分CPU性能。

3、wait/notify機制

4、管道通信:管道流主要用來實現兩個線程之間的二進制數據的傳播

Java 中利用管道實現線程間的通訊

在Java 語言中 提供了各種各樣的輸入輸出流(stream) 使我們能夠很方便的對數據進行操作 其中 管道(pipe)流是一種特殊的流 用於在不同線程(threads)間直接傳送數據 一個線程發送數據到輸出管道 另一個線程從輸入管道中讀數據 通過使用管道 實現不同線程間的通訊 無需求助於類似臨時文件之類的東西 本文在簡要介紹管道的基本概念後 將以一個具體的實例pipeapp加以詳細說明 .管道的創建與使用Java提供了兩個特殊的專門的類專門用於處理管道 它們就是pipedinputstream類和pipeoutputstream類 Pipedinputstream代表了數據在管道中的輸出端 也就是線程向管道讀數據的一端 pipeoutputstream代表了數據在管道中的輸入端 也就是線程向管道寫數據的一端 這兩個類一起使用可以提供數據的管道流 為了創建一個管道流 我們必須首先創建一個pipeoutstream對象 然後 創建pipeinputstream對象 實例如下 pipeout= new pipedyoutstream();pipein= new pipedputsteam(pipepout);一旦創建了一個管道後 就可以象操作文件一樣對管道進行數據的讀寫 .演示程序 pipeapp應用程序由三個程序組成 主線程(pipeapp Java)及由主線程啟動的兩個二級線程(ythread Java和zthread Java) 它們使用管道來處理數據 程序從一個內容為一行一行 x 字母的 input txt 文件中讀取數據 使用管道傳輸數據 第一次是利用線程ythread將數據 x 轉換為 y 最後利用線程zthread將 y 轉換為 z 之後 程序在屏幕上顯示修改後的數據 主線程 (pipeapp Java)在main()方法中 程序首先創建一個應用對象 pipeapp pipeapp=new pipeapp();由於程序中流操作都需要使用IOException異常處理 所以設置了一個try塊 在try中 為了從源文件中讀取數據 程序為 input txt 文件創建了一個輸入流Xfileln :fileinputstream xfileln= new fileinputstream( input txt );新的輸入流傳遞給changetoy()方法 讓線程ythread能讀取該文件 inputstream ylnpipe =pipeapp changetoy(xfileln);changetoy()方法創建將輸入數據 x 改變到 y 的線程ythread 並返回該線程的輸入管道 inputstream zlnpipe = pipeapp changetoz(ylnpipe);changetoz()方法啟動將數據從 y 改變到 z 的線程zehread 主程序將使用從changetoz()返回的輸入管道 得到以修改的數據 然後 程序將管道輸入流定位到datainputstream對象 使程序能夠使用readline()方法讀取數據 datainputstream inputstream = new datainputstream(zlnpiepe);創建了輸入流以後 程序就可以以行一行的讀取數據病顯示在屏幕上 String str= inputstream readline();While(str!=null){system out println(str); str=inputstream readline();} 顯示完成之後 程序關閉輸入流 inputstream close();changetoy()方法 changetoy()方法首先通過傳遞一個參數inputstream給datainputstream對象來定位資源的輸入流 使程序能使用readline()方法從流中讀取數據 datainputstream xfileln =new datainutstream(inputstream) 然後 changetoy()創建輸出管道和輸入管道 pipeoutstream pipeout = new pipeoutputstream();pipeinputstream pipeln = new pipedinputsteam(pipeout); 為了能夠使用println()方法輸出修改的後的文本行到管道 程序將輸出管道定位到printstream對象 printstream printstream = new printstream(pipeout);現在 程序可以創建將數據從x改變到y的線程 該線程是ythread類的一個對象 他傳遞兩個參數 輸入文件(xfileln)和輸出管道(調用printstream) ythread ythread =new thread(xfileln printstream);之後 程序啟動線程 changetoz()方法changetoz()方法與changetoy()方法很相似 他從changetoy()返回的輸入流開始 datainputstream yfileln= new datainputstream(inputstream);程序創建一個新的管道 pipedoutstream pipeout = new pipedoutputstream();pipedinputstream pipeln = new pipedinputsream(pipeout ); 該線程通過這個新的管道發出修改後的數據(輸入流pipeln )給主程序 源程序如下 ////pipeapp Java pipeapp的主應用程序//import Java io *class pipeapp{public static void main(string[] args){pipeapp pipeapp=new pipeapp();try{fileinputstream xfile =new fileinputstream( input txt );inputstream ylnpipe = pipeapp changetoy(xfileln);inputstream zlnpipe=pipeapp changetoz(ylnpipe);system out println();system out println( here are the results );system out pringln();datainputstream inputstream = nes datainputstream(zlnpipe);string str = inputstream readline();while (str!=null){system out println(str);str=inputstream readline();}inputstream close();}catch(exception e){system out println(e tostring());}}public inputstream changetoy(inputstream inputstream){try{datainputstream pipeout = new datainputsteam(inputstream);pipedoutstream pipeout = new pipedoutputstream();pipedlnsteam pipeln = new pipedlnputstream(pipeout);printstream printstream = new printstream(pipeout);ythread ythread = new ythread(xfileln printstream);ythread start();return pipeln;}catch(exeption e){system out println(x tostring());}return null;}public inputstream changetoz(inputstream inputsteam){try{datainputstream yfileln = new datainputstream(inputstream);pipeoutputstream pipeln = new pipedinputstream(pipeout );printrstream printstream = new printsteam(pipeout );zthread zthread = new zthread(yfileln printstream );zthread start();return pipeln ;}catch(exception e){system out println(e tostring());}return null;}} Ythread類和Zthread類由於ythread類與zthread類基本一樣 在此僅以ythread為例加以說明 Ythread的構造器接收兩個參數 輸入的文件和第一個管道的輸出端 構造器存儲這兩個參數作為類的數據成員  Ythread(datainputstream xfileln pringstream printstream){this xfileln = xfileln;this printstream = printstream;} 線程通過run()方法來處理數據 首先讀取一行數據 確保xstring不為空的情況下循環執行 string xstring = xfileln readline();每讀一行數據 完成一次轉換string ystring = xstring replace( x y );然後將修改後的數據輸出到管道的輸出端 prinstream prinrln(ystring);為了確保所有緩衝區的數據完全進入管道的輸出端 pringstram flush();循環完成後 線程關閉管道輸出流  pringstram close();ythread類的源程序如下 //ythread Java//import Java io *;class ythread exteads thread{datainputstream xfileln;pringstream printstream;ythread(datainputstream xfileln pringstream printstream){this xfileln = xfileln;this printstream = printstream;}public void run(){try{string xstring = xfileln readline();while(xstring!=null){string ystring= xstring replace( x y );printstream pringln(ystring);printstream flush();xstring= xfileln readline();}printstream close();}catch{ioexception e}{system out println(e tostring());}}} pipeapp應用程序使用microsoft visual j++ 編譯 lishixinzhi/Article/program/Java/gj/201311/27508

原創文章,作者:RLRUQ,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/330730.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
RLRUQ的頭像RLRUQ
上一篇 2025-01-16 15:46
下一篇 2025-01-16 15:46

相關推薦

  • Java JsonPath 效率優化指南

    本篇文章將深入探討Java JsonPath的效率問題,並提供一些優化方案。 一、JsonPath 簡介 JsonPath是一個可用於從JSON數據中獲取信息的庫。它提供了一種DS…

    編程 2025-04-29
  • java client.getacsresponse 編譯報錯解決方法

    java client.getacsresponse 編譯報錯是Java編程過程中常見的錯誤,常見的原因是代碼的語法錯誤、類庫依賴問題和編譯環境的配置問題。下面將從多個方面進行分析…

    編程 2025-04-29
  • Java騰訊雲音視頻對接

    本文旨在從多個方面詳細闡述Java騰訊雲音視頻對接,提供完整的代碼示例。 一、騰訊雲音視頻介紹 騰訊雲音視頻服務(Cloud Tencent Real-Time Communica…

    編程 2025-04-29
  • Java Bean加載過程

    Java Bean加載過程涉及到類加載器、反射機制和Java虛擬機的執行過程。在本文中,將從這三個方面詳細闡述Java Bean加載的過程。 一、類加載器 類加載器是Java虛擬機…

    編程 2025-04-29
  • Java Milvus SearchParam withoutFields用法介紹

    本文將詳細介紹Java Milvus SearchParam withoutFields的相關知識和用法。 一、什麼是Java Milvus SearchParam without…

    編程 2025-04-29
  • Java 8中某一周的周一

    Java 8是Java語言中的一個版本,於2014年3月18日發布。本文將從多個方面對Java 8中某一周的周一進行詳細的闡述。 一、數組處理 Java 8新特性之一是Stream…

    編程 2025-04-29
  • Java判斷字符串是否存在多個

    本文將從以下幾個方面詳細闡述如何使用Java判斷一個字符串中是否存在多個指定字符: 一、字符串遍歷 字符串是Java編程中非常重要的一種數據類型。要判斷字符串中是否存在多個指定字符…

    編程 2025-04-29
  • VSCode為什麼無法運行Java

    解答:VSCode無法運行Java是因為默認情況下,VSCode並沒有集成Java運行環境,需要手動添加Java運行環境或安裝相關插件才能實現Java代碼的編寫、調試和運行。 一、…

    編程 2025-04-29
  • Java任務下發回滾系統的設計與實現

    本文將介紹一個Java任務下發回滾系統的設計與實現。該系統可以用於執行複雜的任務,包括可回滾的任務,及時恢復任務失敗前的狀態。系統使用Java語言進行開發,可以支持多種類型的任務。…

    編程 2025-04-29
  • Java 8 Group By 會影響排序嗎?

    是的,Java 8中的Group By會對排序產生影響。本文將從多個方面探討Group By對排序的影響。 一、Group By的概述 Group By是SQL中的一種常見操作,它…

    編程 2025-04-29

發表回復

登錄後才能評論