线程间通讯
线程通讯的方式:
1.wait,notify等待通知
/** * 等待线程(调用wait方法的线程) */ synchronized(共享对象){ //同步代码块,进入条件是获得锁 while(判断条件){ //进行wait线程任务的条件不满足时进入 共享对象.wait() } 线程任务代码 } /** * 通知线程(调用notify方法的线程) */ synchronized(共享对象){ //同步代码块,进入条件是获得锁 线程任务代码 改变wait线程任务的条件 共享对象.notify() }
具体例子
public class WaitNotify {
static boolean flag = true; //等待线程继续执行往下执行的条件 static Object lock = new Object(); //上锁的对象 public static void main(String[] args) throws InterruptedException { Thread waitThread = new Thread(new WaitRunnable(),"waitThread"); //以WaitRunnable为任务类的线程 Thread notifyThread = new Thread(new NotifyRunnable(),"notifyThread"); //以NotifyRunnable为任务类的线程 waitThread.start(); //wait线程启动 Thread.sleep(2000); //主线程休眠2s notifyThread.start(); //notify线程启动 } /** * Runnable等待实现类 * synchronized关键字:可以修饰方法或者以同步块的形式来使用 */ static class WaitRunnable implements Runnable{ @Override public void run() { //对lock加锁 synchronized(lock){ //判断,若flag为true,则继续等待(wait) while(flag){ try { System.out.println( Thread.currentThread().getName()+ "---flag为true,等待 @"+ new SimpleDateFormat("hh:mm:ss").format(new Date()) ); lock.wait(); //等待,并释放锁资源 } catch (InterruptedException e) { e.printStackTrace(); } } //若flag为false,则进行工作 System.out.println( Thread.currentThread().getName()+ "---flag为false,运行 @"+ new SimpleDateFormat("hh:mm:ss").format(new Date()) ); } } } /** * Runnable通知实现类 */ static class NotifyRunnable implements Runnable{ @Override public void run(){ //对lock加锁 synchronized(lock){ //以NotifyRunnable为任务类的线程释放lock锁,并进行通知后,以Wait为任务类的线程才可以跳出循环 System.out.println( Thread.currentThread().getName()+ "---当前持有锁,释放 @"+ new SimpleDateFormat("hh:mm:ss").format(new Date()) ); lock.notifyAll(); //通知所有正在等待的线程从wait返回 flag = false; try { Thread.sleep(5000); //notifyThread线程休眠5s } catch (InterruptedException e) { e.printStackTrace(); } } //再次对lock加锁,并休眠 synchronized (lock){ System.out.println( Thread.currentThread().getName()+ "---再次持有锁,休眠 @"+ new SimpleDateFormat("hh:mm:ss").format(new Date()) ); try { Thread.sleep(2000); //再次让notifyThread线程休眠2s } catch (InterruptedException e) { e.printStackTrace(); } } } } } //该代码示例来自《Java并发编程的艺术》
notifyThread线程并不会在调用notyfiAll方法后就马上释放锁,而是在执行完synchronized代码块的内容后才释放锁。我们在notifyThread线程调用notyfiAll后,将该线程休眠5s。可以从打印结果发现,在notifyThread线程休眠的5s中,即使waitThread线程得到了通知,且继续运行的条件也已满足(flag为flase),但waitThread线程在这5s中依然没有得到执行。在notifyThread线程5s的休眠时间结束后,并从synchronized代码块退出,waitThread线程才继续执行。所以,等待线程在得到通知后,仍然需要等待通知线程释放锁,并且在尝试获得锁成功后才能真正从wait方法中返回,并继续执行
2.volatile共享内存,读写都会刷新线程私有内存
参考自:牛客
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本