Java中如何唤醒“指定的“某个线程
线程状态
- NEW(初始化状态)
线程通过new初始化完成到调用start方法前都处于等待状态。
- RUNNABLE(可执行状态)
线程执行start方法后就处于可以行状态。
- BLOCKED(阻塞状态)
notify方法被调用后线程被唤醒,但是这时notify的synchronized代码段并没有执行完,同步锁没有被释放,所以线程处于BLOCKED状态。直到notify的synchronized代码段执行完毕锁被释放,线程才回到wait所在的synchronized代码段继续执行。
- WAITING(等待状态)
调用sleep或是wait方法后线程处于WAITING状态,等待被唤醒。
- TIMED_WAITING(等待超时状态)
调用sleep或是wait方法后线程处于TIMED_WAITING状态,等待被唤醒或时间超时自动唤醒。
- TERMINATED(终止状态)
在run方法结束后线程处于结束状态。
方法一、使用Lock + Condition 实现唤醒指定的部分线程
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class Test { public static Lock lock = new ReentrantLock(); public static int count = 0 ; public static Condition conditionA = lock.newCondition(); public static Condition conditionB = lock.newCondition(); public static void main(String[] args) { Thread t1 = new Thread() { @Override public void run() { lock.lock(); if (count < 5 ) { System.out.println( "线程1未达到业务要求,暂停中,等待线程2处理到达到要求后唤醒" ); try { conditionA.await(); // 暂停线程并释放锁 System.out.println( "conditionA被唤醒" ); conditionB.await(); System.out.println( "conditionB被唤醒" ); System.out.println( "我是线程1后面的代码" ); } catch (InterruptedException e) { e.printStackTrace(); } } lock.unlock(); } }; Thread t2 = new Thread() { @Override public void run() { lock.lock(); while (count < 10 ) { count++; System.out.println( "线程2业务处理中: " + count); try { Thread.sleep( 1000 ); if (count == 5 ) { conditionA.signal(); System.out.println( "唤醒线程1" ); lock.unlock(); // 调用signal()方法后,线程2并不会释放锁,需要手动释放线程2才会执行 } } catch (InterruptedException e) { e.printStackTrace(); } } try { lock.lock(); // 不加这个会报java.lang.IllegalMonitorStateException System.out.println( "等待3秒后conditionB会被唤醒" ); Thread.sleep( 3000 ); conditionB.signal(); } catch (InterruptedException e) { e.printStackTrace(); } lock.unlock(); // 这里释放锁,线程2执行完,线程1才会执行 } }; t1.start(); t2.start(); } } |
方法二、使用Java6引入的LockSupport这个类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import java.util.concurrent.locks.LockSupport; public class TestLockSupport { public static void main(String[] args) throws InterruptedException { Thread t = new Thread(()->{ System.out.println( "start" ); LockSupport.park(); //一直wait System.out.println( "continue" ); }); t.start(); Thread.sleep( 2000 ); LockSupport.unpark(t); //指定t线程解除wait态 } } |
方法三、synchronized + wait + notify
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | import java.util.concurrent.TimeUnit; public class TestNotify extends Thread{ public static void main(String[] args) { final Object synObj = new Object(); Thread t1 = new Thread( new Runnable() { @Override public void run() { synchronized (synObj) { System.out.println( "1.T1获取synObj的对象监视器,开始执行同步块" ); try { TimeUnit.SECONDS.sleep( 2 ); //休息一分钟,不放弃锁 System.out.println( "T1在 wait()时挂起了" ); synObj.wait(); System.out.println( "T1被其他线程唤醒后并重新获得synObj的对象监视器,继续执行" ); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println( "T1获取synObj的对象监视器,结束同步块" ); } }; }); t1.start(); Thread t2 = new Thread( new Runnable() { @Override public void run() { System.out.println( "T2启动,但是因为有别的线程占用了synObj的对象监视器,则等待别的线程执行synObj.wait来释放它" ); synchronized (synObj) { try { System.out.println( "T2获取synObj的对象监视器,进入同步块" ); synObj.notify(); System.out.println( "T2执行synObj.notify()" ); TimeUnit.SECONDS.sleep( 2 ); System.out.println( "T2结束同步块,释放synObj的对象监视器" ); } catch (InterruptedException e) { e.printStackTrace(); } } }; }); t2.start(); Thread t3 = new Thread( new Runnable() { @Override public void run() { System.out.println( "T3启动,但是因为有别的线程占用了synObj的对象监视器,则等待别的线程执行synObj.wait来释放它" ); synchronized (synObj) { try { System.out.println( "T3获取synObj的对象监视器,进入同步块" ); synObj.notify(); System.out.println( "T3执行synObj.notify()" ); TimeUnit.SECONDS.sleep( 2 ); System.out.println( "T3结束同步块,释放synObj的对象监视器" ); } catch (InterruptedException e) { e.printStackTrace(); } } }; }); t3.start(); } } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具