Java中如何实现线程通信
发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,今天就跟大家聊聊有关Java中如何实现线程通信,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、synchronized加wait/notif
千家信息网最后更新 2026年11月03日Java中如何实现线程通信
今天就跟大家聊聊有关Java中如何实现线程通信,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。
1、synchronized加wait/notify方式
/** * wait和notify的使用 * wait和notify必须应用在synchronized块或方法内 * 下面的代码向跳交谊舞一样互相控制着对方的输出 */public class MutiThread_WaitNotify { public static void main(String[] args) { final Object lock = new Object(); Thread a = new Thread(new Runnable(){ @Override public void run(){ synchronized (lock){ try{ lock.wait(); System.out.println("A-1"); lock.notify(); lock.wait(); System.out.println("A-2"); lock.notify(); lock.wait(); System.out.println("A-3"); lock.notify(); }catch(InterruptedException e){ e.printStackTrace(); } } } }); Thread b = new Thread(new Runnable(){ @Override public void run(){ synchronized (lock){ try{ System.out.println("B-1"); lock.notify(); lock.wait(); System.out.println("B-2"); lock.notify(); lock.wait(); System.out.println("B-3"); lock.notify(); lock.wait(); System.out.println("B-4"); }catch(InterruptedException e){ e.printStackTrace();; } } } }); a.start(); b.start(); }}2、ReentrantLock加Condition方式
/** * ReentrantLock和Condition的使用 * 在使用Conditioin的await和signal时,必须将这两个方法写在ReentrantLock的lock方法之后 */public class MutiThread_ReentrantLock_Condition { public static void main(String[] args) { ReentrantLock lock = new ReentrantLock(); Condition condition = lock.newCondition(); int i=1; for(; i<=6; i++){ final int k = i; Thread t1 = new Thread(new Runnable() { @Override public void run() { try{ lock.lock(); System.out.println("ThreadNo:A" + k + " is locked"); // 通过condition.await将线程阻塞 condition.await(); }catch(InterruptedException e){ e.printStackTrace(); }finally{ lock.unlock(); System.out.println("ThreadNo:A"+k + " is unlocked"); } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { if(k == 6){ try{ lock.lock(); System.out.println("All Threads is signaled"); // 通过condition.signalAll唤醒所有线程 condition.signalAll(); }catch(Exception e){ e.printStackTrace(); }finally{ lock.unlock(); } }else{ System.out.println("threads can't signaled, wait a moment."); } } }); t1.start(); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } t2.start(); } }}3、闭锁方式
import java.util.concurrent.CountDownLatch;/** * 闭锁的使用 * 闭锁用于等待事件,当闭锁到达结束状态(本例中是闭锁的计数器值减为0)之前,所有线程都等待,当闭锁到达结束状态时,所有线程都通过 * 闭锁是一次性的,当闭锁到达结束状态后,将不会被重置,这个锁会永远打开并允许所有线程通过。 * 可以将代码中的NUM变量值变为2和4,分别试试什么效果 */public class MutiThread_CountDownLatch { public static void main(String[] args) { // 定义闭锁,并设置闭锁的计数器值为3 CountDownLatch lock = new CountDownLatch(3); // 循环定义3个线程 int NUM = 3; for(int i=1; i<=NUM; i++){ final int k = i; Thread a = new Thread(new Runnable(){ @Override public void run(){ try{ Thread.sleep(k * 1000); System.out.println("ThreadNo:A"+k); // 每个线程在休眠指定时间后将闭锁的计数器值减1,当闭锁的计数器值减到0时,闭所将被打开,从而使第二个循环中的所有线程才能通过 lock.countDown(); // 打印闭锁计数器的值 System.out.println("ThreadNo:A"+k+"; getCount:"+lock.getCount()); }catch(InterruptedException e){ e.printStackTrace(); } } }); a.start(); } // 循环定义2个线程 for(int i=1; i<=2; i++){ final int k = i; Thread b = new Thread(new Runnable(){ @Override public void run(){ try{ System.out.println("ThreadNo:B"+k+" is waiting..."); // 当闭锁的计数器值不为0时,线程将在此处被中断 lock.await(); // 当闭锁的计数器值等于0时,闭锁将被打开,所有等待的线程都将被唤醒 System.out.println("ThreadNo:B"+k+" is notify"); }catch(InterruptedException e){ e.printStackTrace(); } } }); b.start(); } }}4、栅栏的方式
import java.util.concurrent.BrokenBarrierException;import java.util.concurrent.CyclicBarrier;/** * 栅栏的使用 * 栅栏用于等待线程,所有线程必须同时到达栅栏,才能继续执行 * 栅栏不是一次性的,可以被重置。 * 可以将代码中的NUM变量值变为5和7,分别试试什么效果 */public class MutiThread_CyclicBarrier { public static void main(String[] args) { // 定义栅栏,并设置栅栏需要等待的线程数为6 CyclicBarrier barrier = new CyclicBarrier(6); int NUM = 100; for(int i=1; i<=NUM; i++){ final int k = i; Thread t = new Thread(new Runnable() { @Override public void run() { try{ Thread.sleep(k * 1000); System.out.println("ThreadNo:"+k+" is waiting, getNumberWaiting:" + barrier.getNumberWaiting()); // 栅栏设置的等待线程数为6,当线程数不够6个时,所有线程将在此等待 barrier.await(); // 当线程数达到6个时,栅栏将被打开,所有线程都将被唤醒 System.out.println("ThreadNo:"+k+" is notify"); // 栅栏被重置,以便下次继续使用 barrier.reset(); }catch(InterruptedException e){ e.printStackTrace(); } catch (BrokenBarrierException e) { e.printStackTrace(); } } }); t.start(); } }}5、信号量的方式
import java.util.ArrayList;import java.util.List;import java.util.concurrent.Semaphore;/** * 信号量的使用 * 信号量用于控制同时访问某个资源的线程数量,信号量还可以用于实现某个资源池。 * 信号量管理者一组虚拟的许可,线程在执行操作时首先要获得许可,如果信号量的许可数量为0,那么accquire将阻塞直到有许可为止 * 信号量不是一次性的,当信号链的许可用完之后,可以通过release释放许可 */public class MutiThread_Semaphore { public static void main(String[] args) { // 定义信号量,并设置信号量的允许发放的最大许可数量为6 final Semaphore semaphore = new Semaphore(6); // 定义集合,当信号量未发放的许可数量大于0则允许线程向集合内添加元素 final List set = new ArrayList<>(); int i = 1; while(true){ final int k = i++; Thread t = new Thread(new Runnable() { @Override public void run() { boolean res = false; try{ System.out.println("ThreadNo:A"+k+", availablePermits:"+semaphore.availablePermits()); // 当信号量允许发放的许可数量大于0,则会向集合内添加元素,否则将被中断于此 semaphore.acquire(); res = set.add("1"); System.out.println("ThreadNo:A"+k+" add item success"); }catch(InterruptedException e){ e.printStackTrace(); }finally{ if(!res){ semaphore.release(); } } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { if(semaphore.availablePermits() == 0){ // 如果信号量允许发放的许可数量等于0,则释放制定数量的许可 semaphore.release(3); //释放3个许可 System.out.println("ThreadNo:B"+k+" releasePermitNum:"+semaphore.availablePermits()); } } }); t.start(); t2.start(); System.out.println("the num of set:"+set.size()); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } } }} A、join的使用
/** * join的使用 * 实现当调用join的线程执行完毕后,其他线程才能执行 */public class MutiThread_Join { public static void main(String[] args) { Thread a = new Thread(new Runnable(){ @Override public void run(){ printNumber("A"); } }); Thread b = new Thread(new Runnable(){ @Override public void run(){ printNumber("B"); } }); try{ a.start(); // a线程执行完毕后,b线程才能执行 a.join(); b.start(); }catch(InterruptedException e){ e.printStackTrace();; } } public static void printNumber(String s){ System.out.println(s+" print:"+s); }}B、yield的使用
/** * yield,当一个线程中调用了这个方法后,这个线程就会把自己的CPU执行时间让给自己或其它线程, * 注意是让给自己或其它线程,并不是单纯让给其他线程。yield执行后,能让当前线程由运行状态 * 进入到就绪状态,将自己的CPU时间片让出来,让出来之后有可能是其它线程执行,也有可能是该线程 * 继续执行。优先级高的线程并不一定是首先执行,而是首先执行的概率会高一些。优先级在大量线程 * 执行的时候才能体现的出来。 */public class MutiThread_yield { public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { for(int i=0;i<10;i++){ System.out.println("ThreadNo:A"+i); Thread.yield(); } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { for(int i=0;i<10;i++){ System.out.println("ThreadNo:B"+i); Thread.yield(); } } }); t1.setPriority(Thread.MIN_PRIORITY); t2.setPriority(Thread.MAX_PRIORITY); t1.start(); t2.start(); }}看完上述内容,你们对Java中如何实现线程通信有进一步的了解吗?如果还想了解更多知识或者相关内容,请关注行业资讯频道,感谢大家的支持。
线程
信号
信号量
栅栏
数量
计数器
方式
状态
方法
一次性
代码
内容
时间
循环
通信
优先级
元素
同时
效果
资源
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
上海挚品互联网科技有限公司
湖北九亚互联网络科技有限公司
华服互联网科技怎么样
金融科技 互联网金融
万易互联网科技有限公司
上海喔噻互联网科技
赫美联合互联网科技
广州善班互联网科技
深圳艾佳互联网科技
佳云科技和互联网广告
武汉健翔互联网络科技有限公司
崇明区互联网教育科技售后服务
坤平互联网科技
卓翼科技产业互联网合作
浙南科技城互联网大厦招聘
工业互联网科技成果转化
下一代互联网重大应用科技园
艺电能源互联网科技有限公司招聘
宁波允成互联网科技有限公司
如何强化互联网金融科技
互联网科技海报
科技与互联网
互联网下的科技发展
赫美联合互联网科技
广州善班互联网科技
互联网科技宣传片
互联网金融和金融科技
云创客互联网科技公司
996高科技互联网公司
山东有哪些互联网科技公司