Java并發(fā)編程線程間通訊實(shí)現(xiàn)過程詳解
在Java中線程間通訊有多種方式,我這里列出一些常用方式,并用代碼的方式展示他們是如何實(shí)現(xiàn)的:
- 共享變量
- wait, notify,notifyAll(這3個方法是Object對象中的方法,且必須與synchronized關(guān)鍵字結(jié)合使用)
- CyclicBarrier、CountDownLatch
- 利用LockSupport
- Lock/Condition機(jī)制
- 管道,創(chuàng)建管道輸出流PipedOutputStream和管道輸入流PipedInputStream
示例一:
package com.zhi.test; import java.util.concurrent.CountDownLatch; import java.util.concurrent.atomic.AtomicInteger; import org.junit.Test; /** * Java多線程-線程通訊示例<br> * flag作為共享變量JobB執(zhí)行,notify通知Job執(zhí)行,CountDownLatch通知主線程執(zhí)行 * * @author 張遠(yuǎn)志 * @since 2020年5月4日21:51:24 * */ public class ThreadTest2 { private CountDownLatch latch; private volatile boolean flag = true; private Object lock = new Object(); private AtomicInteger num = new AtomicInteger(0); class JobA implements Runnable { @Override public void run() { synchronized (lock) { flag = false; if (num.get() != 3) { try { lock.wait(); // wait方法會釋放鎖 } catch (InterruptedException e) { } } System.out.println("任務(wù)A收到通知,繼續(xù)執(zhí)行作業(yè)"); } latch.countDown(); } } class JobB implements Runnable { @Override public void run() { while (flag) { // 保證JobA先申請到鎖 } synchronized (lock) { for (int i = 1; i <= 5; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { } int a = num.incrementAndGet(); System.out.println("任務(wù)B第" + i + "次執(zhí)行,num值為:" + a); if (a == 3) { lock.notify(); // 喚醒JobB線程,notify方法不會釋放鎖 } } } latch.countDown(); } } @Test public void test() { latch = new CountDownLatch(2); new Thread(new JobA()).start(); new Thread(new JobB()).start(); try { latch.await(); // 保證2個線程都執(zhí)行完畢 } catch (InterruptedException e) { } } }
結(jié)果輸出:
任務(wù)B第1次執(zhí)行,num值為:1
任務(wù)B第2次執(zhí)行,num值為:2
任務(wù)B第3次執(zhí)行,num值為:3
任務(wù)B第4次執(zhí)行,num值為:4
任務(wù)B第5次執(zhí)行,num值為:5
任務(wù)A收到通知,繼續(xù)執(zhí)行作業(yè)
示例二:
package com.zhi.test; import java.util.concurrent.CountDownLatch; import java.util.concurrent.locks.LockSupport; import org.junit.Test; /** * Java多線程-線程通訊示例,利用LockSupport * * @author 張遠(yuǎn)志 * @since 2020年5月4日21:51:24 * */ public class ThreadTest3 { private CountDownLatch latch; private volatile int num = 0; private Thread ta; private Thread tb; class JobA implements Runnable { @Override public void run() { if (num != 3) { LockSupport.park(); } System.out.println("任務(wù)A收到通知,繼續(xù)執(zhí)行作業(yè)"); latch.countDown(); } } class JobB implements Runnable { @Override public void run() { for (int i = 1; i <= 5; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { } num++; System.out.println("任務(wù)B第" + i + "次執(zhí)行,num值為:" + num); if (num == 3) { LockSupport.unpark(ta); // unpark會立即激活傳入線程 } } latch.countDown(); } } @Test public void test() { latch = new CountDownLatch(2); ta = new Thread(new JobA()); tb = new Thread(new JobB()); ta.start(); tb.start(); try { latch.await(); // 保證2個線程都執(zhí)行完畢 } catch (InterruptedException e) { } } }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java結(jié)合uniapp實(shí)現(xiàn)驗(yàn)證碼功能的示例詳解
UniApp 是一個基于 Vue.js 的跨平臺應(yīng)用開發(fā)框架,允許開發(fā)者使用統(tǒng)一的代碼庫來構(gòu)建多平臺應(yīng)用,這篇文章將給大家介紹Java結(jié)合uniapp實(shí)現(xiàn)驗(yàn)證碼功能,文中通過詳細(xì)的代碼示例講解的非常詳細(xì),需要的朋友可以參考下2024-07-07Spring Cloud 專題之Sleuth 服務(wù)跟蹤實(shí)現(xiàn)方法
這篇文章主要介紹了Spring Cloud 專題之Sleuth 服務(wù)跟蹤,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-08-08java8 stream 由一個list轉(zhuǎn)化成另一個list案例
這篇文章主要介紹了java8 stream 由一個list轉(zhuǎn)化成另一個list案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08