线程间通讯

线程通讯的方式:

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共享内存,读写都会刷新线程私有内存

参考自:牛客

posted @   northli  阅读(57)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示