日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CompletableFuture的多线程和异步监听实现

發(fā)布時間:2023/12/10 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CompletableFuture的多线程和异步监听实现 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
大家好,我是烤鴨:
今天給大家說的是多線程并發(fā)的異步監(jiān)聽的情況。
這里不得不說一下CompletableFuture這個類,普通我們執(zhí)行多線程的時候只需要另外啟動一條線程。
說一下線程的3種方式:

extends Thread,implements Runnable,implements Callable。

? ? ? ? 同步的實現(xiàn)方式有很多。這里貼一下我的。

? ? ? ?這個handler是可以注入其他的比如service或者dao,完成業(yè)務(wù)邏輯,我這里是注入的redis。

package com.mys.my.wechat.handler;import com.mys.my.wechat.config.redis.RedisClient; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.concurrent.Executor;@Service("musicHandler") public class MusicHandler {public static Log logger = LogFactory.getLog(MusicHandler.class);public String redisString;public String openId;@Autowiredprivate RedisClient redisClient;@Autowiredprivate Executor taskAsyncPool;public void doAllHandler() {try {taskAsyncPool.execute(new Runnable() {@Overridepublic void run() {logger.info("xiami 任務(wù)啟動");Date time = new Date(); // SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // String re_StrTime = sdf.format(time);//過期時間1小時redisClient.set("xiamiMusic:"+openId,redisString,60*60);}});} catch (Exception e) {e.printStackTrace();}} }

調(diào)用:

//存redismusicHandler.redisString = toJson;musicHandler.openId = openId;musicHandler.doAllMusicHandler();

以上就是同步調(diào)用,但是這樣只是執(zhí)行,你無法監(jiān)聽結(jié)果。

我現(xiàn)在說一下場景:

燒水的同時,洗衣機洗衣服,電腦下載,手機充電,我們生活中

也會有同時干幾件事的情況,而需求是這幾件事都干完了我才能出門,多線程確實能執(zhí)行,但是怎么監(jiān)聽結(jié)果呢。

以上也許可以說時間是可以預測的。

但是具體的業(yè)務(wù)場景,如果需要你去調(diào)用4個接口,而他們之間的沒有任何影響,但是又必須

4個接口都執(zhí)行完才能返回數(shù)據(jù)。這樣如果實現(xiàn)多線程的異步監(jiān)聽呢?

最常用的就是爬蟲,我想同時抓取幾個網(wǎng)站或者幾個網(wǎng)頁的數(shù)據(jù),如果是單線程,效率很低。

多線程又必須保證每條線程完成抓取并返回數(shù)據(jù)。以下是一個小例子。

用CompletableFuture,代碼如下:

package com.mys.my.wechat.service.impl;import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.concurrent.CompletableFuture;final Integer res = 0;final ArrayList<Integer> integers = new ArrayList<>();CompletableFuture<Integer> completableFuture1 = CompletableFuture.supplyAsync(() -> {//模擬執(zhí)行耗時任務(wù)System.out.println("task 1 doing...");try {Thread.sleep(1000);} catch (Exception e) {e.printStackTrace();}//返回結(jié)果return 1;});//注冊完成事件completableFuture1.thenAccept(result -> {integers.add(1);});CompletableFuture<Integer> completableFuture2 = CompletableFuture.supplyAsync(() -> {//模擬執(zhí)行耗時任務(wù)System.out.println("task 2 doing...");try {Thread.sleep(2000);} catch (Exception e) {e.printStackTrace();}//返回結(jié)果return 1;});//注冊完成事件completableFuture2.thenAccept(result -> {integers.add(1);});CompletableFuture<Integer> completableFuture3 = CompletableFuture.supplyAsync(() -> {//模擬執(zhí)行耗時任務(wù)System.out.println("task 3 doing...");try {Thread.sleep(3000);} catch (Exception e) {e.printStackTrace();}//返回結(jié)果return 1;});//注冊完成事件completableFuture3.thenAccept(result -> {integers.add(1);});while(true){try {Thread.sleep(1000);if(integers.size()== 3){System.out.println("done");break;}System.out.println("s:"+integers.size());} catch (InterruptedException e) {e.printStackTrace();}}}這里我們可以看到,主線程一直在監(jiān)聽,其他新開啟的3個線程,如果他們執(zhí)行完畢,就可以返回數(shù)據(jù),
如果他們有沒執(zhí)行完的,主線程就一直等。這樣就分工明確了,主線程的任務(wù)就是監(jiān)視其他是否完畢,

而同時開啟3條線程執(zhí)行速度也會很快。

這只是一個demo和想法實現(xiàn),歡迎交流。


總結(jié)

以上是生活随笔為你收集整理的CompletableFuture的多线程和异步监听实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。