在Java項目中怎么樣實現(xiàn)調(diào)度多線程?針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
專注于為中小企業(yè)提供成都網(wǎng)站建設(shè)、網(wǎng)站設(shè)計服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)德保免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴充和轉(zhuǎn)變。方法一:設(shè)置線程優(yōu)先級。
java.lang.Thread 提供了 setPriority(int newPriority) 方法來設(shè)置線程的優(yōu)先級,但線程的優(yōu)先級是無法保障線程的執(zhí)行次序的,優(yōu)先級只是提高了優(yōu)先級高的線程獲取 CPU 資源的概率。也就是說,這個方法不靠譜。
方法二:使用線程合并。
使用 java.lang.Thread 的 join() 方法。比如有線程 a,現(xiàn)在當(dāng)前線程想等待 a 執(zhí)行完之后再往下執(zhí)行,那就可以使用 a.join()。一旦線程使用了 a.join(),那么當(dāng)前線程會一直等待 a 消亡之后才會繼續(xù)執(zhí)行。什么時候 a 消亡?a 的 run() 方法執(zhí)行結(jié)束了 a 就消亡了。
這個方法可以有效地進行線程調(diào)度,但卻只能局限于等待一個線程的執(zhí)行調(diào)度。如果要等待 N 個線程的話,顯然是無能為力了。而且等待線程必須在被等待線程消亡后才得到繼續(xù)執(zhí)行的指令,無法做到兩個線程真正意義上的并發(fā),靈活性較差。
方法三:使用線程通信。
java.lang.Object 提供了可以進行線程間通信的 wait 與 notify 、notifyAll 等方法。每個 Java 對象都有一個隱性的線程鎖的概念,通過這個線程鎖的概念我們讓線程間可以進行通信,各線程不再埋頭單干。著名的“生產(chǎn)者-消費者”模型就是基于這個原理實現(xiàn)的。
這個方法也可以有效地進行線程調(diào)度,而且也不僅僅局限于等待一個線程的執(zhí)行調(diào)度,具有很大程度上的靈活性。但操作復(fù)雜,不易控制容易造成混亂,程序維護起來也不太方便。
方法四:使用閉鎖。
閉鎖就像一扇門,在先決條件未達成之前這扇門是閉著的,線程無法通過,先決條件達成之后,閉鎖打開,線程就可以繼續(xù)執(zhí)行了。java.util.concurrent.CountDownLatch 是一個很實用的閉鎖實現(xiàn),它提供了 countDown() 和 await() 方法達成線程執(zhí)行隊列,這個方法最適合 M 個線程等待 N 個線程執(zhí)行結(jié)束再執(zhí)行的情況。首先初始化一個 CountDownLatch 對象,比如 CountDownLatch doneSignal = new CountDownLatch(N);該對象具有 N 作為計數(shù)閥值,每個被等待線程通過對 doneSignal 對象的持有,使用 countDown() 可以將 doneSignal 的計數(shù)閥值減一;每個等待線程通過對 doneSignal 對象的持有,使用 await() 阻塞當(dāng)前線程,直到 doneSignal 計數(shù)閥值減為 0,才繼續(xù)往下執(zhí)行。
這個方法也可以有效地進行線程調(diào)度,而且比方法三更易于管理,開發(fā)者只需控制好 CountDownLatch 即可。但線程執(zhí)行次序管理相對單一,它只是指出當(dāng)前等待線程的數(shù)量,而且 CountDownLatch 的初始閥值一旦設(shè)置就只能遞減下去,無法重置。如需遞減過程中進行閥值的重置可以參考 java.util.concurrent.CyclicBarrier。
不管如何,CountDownLatch 對于一定條件下的線程隊列的達成還是很有用的。對于復(fù)雜環(huán)境下的線程管理還是卓有成效的。所以熟悉和把握對它的使用還是很有必要的。
以下是一個實際項目中 CountDownLatch 的使用的例子:
private Map<Long,DecryptSignalAndPath> afterDecryptFilePathMap = new HashMap<Long,DecryptSignalAndPath>();//TODO 注意容器垃圾數(shù)據(jù)的清理工作 class DecryptRunnable implements Runnable { private ServerFileBean serverFile; private Long fid;//指向解密文件 private CountDownLatch decryptSignal; protected DecryptRunnable(Long fid, ServerFileBean serverFile, CountDownLatch decryptSignal) { this.fid = fid; this.serverFile = serverFile; this.decryptSignal = decryptSignal; } @Override public void run() { //開始解密 String afterDecryptFilePath = null; DecryptSignalAndPath decryptSignalAndPath = new DecryptSignalAndPath(); decryptSignalAndPath.setDecryptSignal(decryptSignal); afterDecryptFilePathMap.put(fid, decryptSignalAndPath); afterDecryptFilePath = decryptFile(serverFile); decryptSignalAndPath.setAfterDecryptFilePath(afterDecryptFilePath); decryptSignal.countDown();//通知所有阻塞的線程 } } class DecryptSignalAndPath { private String afterDecryptFilePath; private CountDownLatch decryptSignal; public String getAfterDecryptFilePath() { return afterDecryptFilePath; } public void setAfterDecryptFilePath(String afterDecryptFilePath) { this.afterDecryptFilePath = afterDecryptFilePath; } public CountDownLatch getDecryptSignal() { return decryptSignal; } public void setDecryptSignal(CountDownLatch decryptSignal) { this.decryptSignal = decryptSignal; } }
分享名稱:在Java項目中怎么樣實現(xiàn)調(diào)度多線程-創(chuàng)新互聯(lián)
網(wǎng)頁鏈接:http://jinyejixie.com/article28/dipscp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供用戶體驗、做網(wǎng)站、網(wǎng)站制作、建站公司、網(wǎng)站策劃、搜索引擎優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容