Java異步處理機(jī)制實(shí)例詳解
通常同步意味著一個(gè)任務(wù)的某個(gè)處理過程會對多個(gè)線程在用串行化處理,而異步則意味著某個(gè)處理過程可以允許多個(gè)線程同時(shí)處理。下面我們就來看看有關(guān)異步處理的詳細(xì)內(nèi)容。
異步通常代表著更好的性能,因?yàn)樗艽蟪潭壬弦蕾囉诰彌_,是典型的使用空間換時(shí)間的做法,例如在計(jì)算機(jī)當(dāng)中,高速緩存作為cpu和磁盤io之間的緩沖地帶協(xié)調(diào)cpu高速計(jì)算能力和磁盤的低速讀寫能力。
volatile
應(yīng)用場景:檢查一個(gè)應(yīng)用執(zhí)行關(guān)閉或中斷狀態(tài)。因?yàn)榇岁P(guān)鍵字拒絕了虛擬對一個(gè)變量多次賦值時(shí)的優(yōu)化從而保證了虛擬機(jī)一定會檢查被該關(guān)鍵字修飾的變量的狀態(tài)變化。
CountDownLatch
應(yīng)用場景:控制在一組線程操作執(zhí)行完成之前當(dāng)前線程一直處于等待。例如在主線程中執(zhí)行await()方法阻塞主線程,在工作線程執(zhí)行完邏輯后執(zhí)行countDown()方法。
本文示例場景:
1,從控制臺發(fā)送消息到消息服務(wù)器(由一個(gè)隊(duì)列模擬)。
2,將消息隊(duì)列寫入到文件(對寫文件的操作設(shè)置延時(shí)以模擬性能瓶頸)。
3,消息服務(wù)器作為控制臺和文件寫入之間的緩沖區(qū)。
示例代碼:
注:往消息隊(duì)列添加消息可以通過for循環(huán)一次性加入,本文為了便于觀察文件和隊(duì)列的變化而采用了控制臺輸入,實(shí)際寫一行文件記錄速度應(yīng)該高于手速,所以本文示例中增加了線程sleep時(shí)間。
package org.wit.ff.ch2; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.util.Scanner; import java.util.concurrent.BlockingQueue; import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; /** * * <pre> * 簡單異步處理示例. * </pre> * * @author F.Fang * @version $Id: AsyncHandler.java, v 0.1 2014年10月23日 下午11:37:54 F.Fang Exp $ */ public class AsyncHandler { /** * 控制資源釋放. */ private CountDownLatch latch; /** * 處理完成標(biāo)識. */ private volatile boolean handleFinish; /** * 消息寫入本地文件完成. */ private volatile boolean sendFinish; /** * 阻塞隊(duì)列. */ private BlockingQueue<String> queue; private BufferedWriter bw; public AsyncHandler(CountDownLatch latch) { this.latch = latch; /** * 使用鏈表實(shí)現(xiàn). */ queue = new LinkedBlockingQueue<String>(); File file = new File("E:/hello.txt"); try { bw = new BufferedWriter(new FileWriter(file)); } catch (IOException e) { throw new RuntimeException(e); } } public void handle() { // 模擬性能瓶頸的執(zhí)行過程,3s處理一條消息. new Thread() { public void run() { while (!handleFinish) { try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e1) { // 不做處理. } String s = queue.peek(); if (s != null) { queue.poll(); try { bw.write(s); bw.newLine(); } catch (IOException e) { } } // 若隊(duì)列為空并且消息發(fā)送完成. if (queue.isEmpty() && sendFinish) { // 計(jì)數(shù)器1->0 latch.countDown(); // 讓處理過程結(jié)束. handleFinish = true; break; } } } }.start(); } /** * * <pre> * 給出消息發(fā)送完成的標(biāo)識. * </pre> * */ public void sendFinish() { sendFinish = true; } /** * * <pre> * 資源釋放. * </pre> * */ public void release() { System.out.println("release!"); if (bw != null) { try { bw.close(); } catch (IOException e) { // TODO 打印日志. } } //其實(shí)使用queue = null就夠了. if (queue != null) { queue.clear(); queue = null; } } /** * * <pre> * 往隊(duì)列發(fā)送消息. * </pre> * * @param text */ public void sendMsg(String text) { if (text != null && !text.isEmpty()) { queue.add(text); } } public static void main(String[] args) { CountDownLatch latch = new CountDownLatch(1); AsyncHandler handler = new AsyncHandler(latch); handler.handle(); // 做一次檢查. Scanner scanner = new Scanner(System.in); while (true) { String text = scanner.next(); // 若用戶選擇退出. if ("exit".equals(text)) { // 表示消息已經(jīng)發(fā)送完成. handler.sendFinish(); break; } handler.sendMsg(text); } try { // 阻塞主線程等待消息寫入到本地文件完成. latch.await(); } catch (InterruptedException e) { e.printStackTrace(); } // 釋放資源 文件流,隊(duì)列. handler.release(); // 關(guān)閉控制臺輸入. scanner.close(); } }
總結(jié)
以上就是本文關(guān)于異步機(jī)制的全部內(nèi)容,實(shí)例代碼中的注釋還是比較詳細(xì)的,如果有什么問題可以留言,小編會及時(shí)回復(fù)大家。同時(shí)也感謝大家對本站的支持!
相關(guān)文章
SSH框架網(wǎng)上商城項(xiàng)目第25戰(zhàn)之使用java email給用戶發(fā)送郵件
這篇文章主要為大家詳細(xì)介紹了SSH框架網(wǎng)上商城項(xiàng)目第25戰(zhàn)之使用java email給用戶發(fā)送郵件,感興趣的小伙伴們可以參考一下2016-06-06淺談?dòng)肧pringBoot實(shí)現(xiàn)策略模式
本文主要介紹了SpringBoot實(shí)現(xiàn)策略模式,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-10-10eclipse配置tomcat10的詳細(xì)步驟總結(jié)
今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識,文章圍繞著eclipse配置tomcat10的詳細(xì)步驟展開,文中有非常詳細(xì)的介紹及圖文示例,需要的朋友可以參考下2021-06-06java 從int數(shù)組中獲取最大數(shù)的方法
這篇文章主要介紹了java 從int數(shù)組中獲取最大數(shù)的方法,需要的朋友可以參考下2017-02-02SpringBoot2.0解決Long型數(shù)據(jù)轉(zhuǎn)換成json格式時(shí)丟失精度問題
這篇文章主要介紹了SpringBoot2.0解決Long型數(shù)據(jù)轉(zhuǎn)換成json格式時(shí)丟失精度問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06