直播app開發中,關於執行緒需要了解的一些事
一、執行緒 D 在A、B、C都同步執行完畢後執行
我們在直播app開發中要實現的目標是:A、B、C三個執行緒可以同時開始執行,各自獨立執行完成後通知D;D 不會開始執行,直到 A、B 和 C 都執行完畢。所以我們 CountdownLatch 用來實現這種型別的通訊。它的基本用法是:
1、在直播app開發中建立一個計數器,並設定一個初始值, CountdownLatch countDownLatch = new CountDownLatch(3);
2、呼叫countDownLatch.await()進入等待狀態,直到計數值變為0;
3、在其他執行緒呼叫countDownLatch.countDown(),該方法會將計數值減一;
4、當計數器的值變為 0 時,countDownLatch.await()等待執行緒中的方法會繼續執行下面的程式碼。
實現程式碼如下:
public static void runDAfterABC() { int count = 3; CountDownLatch countDownLatch = new CountDownLatch(count); new Thread(() -> { System.out.println("INFO: D 等待 A B C 執行完成"); try { countDownLatch.await(); System.out.println("INFO: A B C 執行完成,D 開始執行"); System.out.println("D is working"); } catch (InterruptedException e) { e.printStackTrace(); } }).start(); for (char threadName = 'A'; threadName <= 'C' ; threadName++) { final String name = String.valueOf(threadName); new Thread(() -> { System.out.println(name + " is working"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + " finished"); countDownLatch.countDown(); }).start(); } }
得到的結果如下:
INFO: D 等待 A B C 執行完成 A is working B is working C is working C finished B finished A finished INFO: A B C 執行完成,D 開始執行 D is working
其實CountDownLatch它本身就是一個倒數計數器,我們把初始的count值設定為3。D執行的時候,首先呼叫該countDownLatch.await()方法檢查計數器的值是否為0,如果不是0則保持等待狀態. A、B、C 執行完畢後,分別使用countDownLatch.countDown()方法將倒數計數器減1。計數器將減為 0,然後通知await()方法結束等待,D開始繼續執行。
因此,CountDownLatch適用於直播app開發中一個執行緒需要等待多個執行緒的情況。
二、三個執行緒分開準備同時開跑
這一次,A、B、C這三個執行緒都需要分別準備,等三個執行緒都準備好後開始同時執行,我們應該如何在直播app開發中做到這一點?
CountDownLatch可以用來計數,但完成計數的時候,只有一個執行緒的一個await()方法會得到響應,所以多執行緒不能在同一時間被觸發。為了達到執行緒相互等待的效果,我們可以使用該CyclicBarrier,其基本用法為:
1、首先在直播app開發中建立一個公共物件CyclicBarrier,並設定同時等待的執行緒數,CyclicBarrier cyclicBarrier = new CyclicBarrier(3);
2、這些執行緒同時開始準備,準備好後,需要等待別人準備好,所以呼叫cyclicBarrier.await()方法等待別人;
3、當指定的需要同時等待的執行緒都呼叫了該cyclicBarrier.await()方法時,意味著這些執行緒準備好了,那麼這些執行緒就會開始同時繼續執行。
想象一下有三個跑步者需要同時開始跑步,所以他們需要等待其他人都準備好,實現程式碼如下:
public static void runABCWhenAllReady() { int count = 3; CyclicBarrier cyclicBarrier = new CyclicBarrier(count); Random random = new Random(); for (char threadName = 'A'; threadName <= 'C' ; threadName++) { final String name = String.valueOf(threadName); new Thread(() -> { int prepareTime = random.nextInt(10000); System.out.println(name + " 準備時間:" + prepareTime); try { Thread.sleep(prepareTime); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + " 準備好了,等待其他人"); try { cyclicBarrier.await(); } catch (InterruptedException | BrokenBarrierException e) { e.printStackTrace(); } System.out.println(name + " 開始跑步"); }).start(); } }
得到結果如下:
A 準備時間:1085 B 準備時間:7729 C 準備時間:8444 A 準備好了,等待其他人 B 準備好了,等待其他人 C 準備好了,等待其他人 C 開始跑步 A 開始跑步 B 開始跑步
CyclicBarrier 的作用就是等待多個執行緒同時執行。
三、子執行緒將結果返回給主執行緒
在直播app開發中,往往我們需要建立子執行緒來做一些耗時的任務,然後將執行結果傳回主執行緒。那麼如何在 Java 中實現呢?
一般在建立執行緒的時候,我們會把 Runnable 物件傳遞給 Thread 執行,Runable 的原始碼如下:
@FunctionalInterface public interface Runnable { public abstract void run(); }
可以看到 Runable 是一個函式式介面,該介面中的 run 方法沒有返回值,那麼如果要返回結果,可以使用另一個類似的介面 Callable。
函式式介面:只有一個方法的介面
Callable 介面的原始碼如下:
@FunctionalInterface public interface Callable<V> { /** * Computes a result, or throws an exception if unable to do so. * * @return computed result * @throws Exception if unable to compute a result */ V call() throws Exception; }
可以看出,最大的區別Callable在於它返回的是泛型。
那麼接下來的問題是,如何將直播app開發中的子執行緒的結果傳回去呢?Java 有一個類,FutureTask,它可以與 一起工作Callable,但請注意,get用於獲取結果的方法會阻塞主執行緒。FutureTask 本質上還是一個 Runnable,所以可以直接傳到 Thread 中。
比如我們想讓子執行緒計算1到100的總和,並將結果返回給主執行緒,程式碼如下:
public static void getResultInWorker() { Callable<Integer> callable = () -> { System.out.println("子任務開始執行"); Thread.sleep(1000); int result = 0; for (int i = 0; i <= 100; i++) { result += i; } System.out.println("子任務執行完成並返回結果"); return result; }; FutureTask<Integer> futureTask = new FutureTask<>(callable); new Thread(futureTask).start(); try { System.out.println("開始執行 futureTask.get()"); Integer result = futureTask.get(); System.out.println("執行的結果:" + result); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } }
得到的結果如下:
開始執行 futureTask.get()子任務開始執行 子任務執行完成並返回結果 執行的結果:5050
可以看出在主執行緒呼叫futureTask.get()方法時阻塞了主執行緒;然後Callable開始在內部執行並返回操作的結果;然後futureTask.get()得到結果,直播app開發主執行緒恢復執行。
在這裡我們可以瞭解到,FutureTask和Callable可以直接在主執行緒中獲取子執行緒的結果,但是它們會阻塞主執行緒。當然,如果你不希望直播app開發阻塞主執行緒,可以考慮使用ExecutorService把FutureTask到執行緒池來管理執行。
本文轉載自網路,轉載僅為分享乾貨知識,如有侵權歡迎聯絡雲豹科技進行刪除處理
原文連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69996194/viewspace-2848356/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- android 關於關於子執行緒更新UI的一些事Android執行緒UI
- 關於 TCP 需要了解的事兒TCP
- Java 關於執行緒的一些使用Java執行緒
- 關於GCD開發的一些事GC
- 提升直播app開發質量,我們需要掌握的二三事APP
- 關於多執行緒的一些細節 (轉)執行緒
- 關於程式和執行緒 自我的一些總結執行緒
- iOS 開發中的多執行緒iOS執行緒
- 安卓開發(Java)中關於final關鍵字與執行緒安全性安卓Java執行緒
- 關於執行緒池,那些你還不知道的事執行緒
- 關於“UI執行緒”UI執行緒
- 細說JavaScript單執行緒的一些事JavaScript執行緒
- 關於執行緒的問題...執行緒
- 關於多執行緒控制執行緒
- 關於多執行緒(轉)執行緒
- HarmonyOS JS應用開發需要關注哪些執行緒?官方解析來啦~JS執行緒
- 關於機器學習需要了解的知識機器學習
- 直播中需要了解的AAC基礎知識
- 關於iOS中的執行緒安全和使用場景iOS執行緒
- 關於redis單執行緒的分析Redis執行緒
- 關於執行緒設計的感受執行緒
- 關於執行緒池的面試題執行緒面試題
- 關於Java併發多執行緒的一點思考Java執行緒
- 教育直播APP開發過程中,如何保持系統正常執行?APP
- python多執行緒中:如何關閉執行緒?Python執行緒
- 實現手機直播原始碼中兩個執行緒依次執行的相關程式碼原始碼執行緒
- 關於Java多執行緒的執行緒同步和執行緒通訊的一些小問題(順便分享幾篇高質量的博文)Java執行緒
- 直播系統開發過程中的一些關鍵點
- java開發之多執行緒需要學習和理解的東西Java執行緒
- 關於redis,你需要了解的幾點!Redis
- 執行緒中斷以及執行緒中斷引發的那些問題執行緒
- 關於執行緒的幾個函式執行緒函式
- 關於linux的執行緒實現Linux執行緒
- 關於Python多執行緒的理解Python執行緒
- JAVA執行緒的那些事?Java執行緒
- Java面試中,一些常見的有關多執行緒問題!Java面試執行緒
- 多執行緒同步的開發執行緒
- js中關於base64的一些事JS