zoukankan      html  css  js  c++  java
  • 线程间的通信

    线程间的通信:


    • 等待唤醒机制 -多个线程在操作同一份数据时,避免对同一变量进行争夺

    目的:有效利用资源
    重点:对资源占用的判断

    TimeWaiting -计时等待


    1. 使用sleep(long m)方法,线程睡醒进入Runnable/Blocked(阻塞状态)
    2. 使用wait(long m),毫秒值结束之后,若未被唤醒,则会进入阻塞状态
    • 注:notify只会唤醒同一锁对象
    1. wait与notify必须在同步代码块或者同步方法中使用
    2. 通过锁对象调用
    public class ThreadWaitNotifyAll {
        public static void main(String[] args) {
            Object obj = new Object();
            //匿名内部类创建一个线程
            new Thread("消费者线程"){
                @Override
                public void run() {
                    //等待唤醒只能有一个线程进行,利用同步机制
                    synchronized (obj) {
                        System.out.println("消费者:老板我要买东西,给你2s");
                        try {
                            obj.wait(2000);  //无限等待,直到被唤醒
                            System.out.println("消费者:收到了,谢谢老板,我带走了");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                    }
                }
            }.start();
            new Thread("消费者1线程"){
                @Override
                public void run() {
                    //等待唤醒只能有一个线程进行,利用同步机制
                    synchronized (obj) {
                        System.out.println("消费者01:老板我要买东西,给你2s");
                        try {
                            obj.wait(2000);  //无限等待,直到被唤醒
                            System.out.println("消费者01:收到了,谢谢老板,我带走了");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                    }
                }
            }.start();
    
            //在创建一个线程
            new Thread("老板线程"){
                @Override
                public void run() {
                    //上面线程等待5s
                    System.out.println("老板:谢谢你们的5s钟");
    
                    synchronized (obj) {
                        System.out.println("老板:我做好了,来拿吧");
                        //会唤醒调度队列队头的进程 obj.notify();
                        //由于是在同步块内,此刻没锁,唤醒后会再获取锁,获取成功RUNNABLE
                        // 若没获取到,会重新进入调度队列 entry set,WAITING转为BLOCKED状态
    
                        //全部唤醒
                        obj.notifyAll();
                    }
    
                }
            }.start();
    
    
        }
    }
    

    等待唤醒案例:


    1. 创建一个线程,告知另一线程需要通信,让其进入WAITING状态(无限等待)
    2. 创建一个另一线程,唤醒上一线程
    • 注:顾客和老板线程必须用同步代码块锁起来,保证有一个在执行
    1. 同步锁对象必须保证唯一
    2. 只有锁对象能调用wait()/notify()方法
    • 在Object类中

    void wait()
    在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
    void notify()
    唤醒在此对象监视器上等待的单个线程。
    void notifyAll()
    唤醒在此对象监视器上等待的所有线程,会继续执行wait之后的方法

    public class ThreadState {
        public static void main(String[] args) {
            Object obj = new Object();
            //匿名内部类创建一个线程
            new Thread("消费者线程"){
                @Override
                public void run() {
                    //等待唤醒只能有一个线程进行,利用同步机制
                    synchronized (obj) {
                        System.out.println("消费者:老板我要买东西");
                        try {
                            obj.wait();  //无限等待,直到被唤醒
                            System.out.println("消费者:收到了,谢谢老板,我带走了");
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
                    }
                }
            }.start();
    
            //在创建一个线程
            new Thread("老板线程"){
                @Override
                public void run() {
                    //花5秒准备东西
                    try {
                        System.out.println("老板:好的,等我五秒钟准备一下");
                        Thread.sleep(0000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    
                    //唤醒一个线程
                    synchronized (obj) {
                        System.out.println("老板:我做好了,来拿吧");
                        obj.notify();  //唤醒上面的线程,执行wait之后的代码,但是该线程还没结束
                        //下面代码仍然在抢占cpu的执行权,因为唤醒后,当前线程还未解锁
                        System.out.println("老板:哈哈,骗你的继续等吧");
                    }
                    //休息会儿让上面的线程先走
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //上面线程结束
                    System.out.println("老板:不客气");
                }
            }.start();
    
    
        }
    }
    
    
  • 相关阅读:
    反转链表
    linux shell 读取配置文件的一个例子
    python 笔记碎片
    工作笔记整理
    linux服务器之间文件互传
    工作软件收集
    linux同步时间
    利用linux的df和du命令查看文件和目录的内存占用
    windows常用快捷键
    SUSE 12 安装 python3.6
  • 原文地址:https://www.cnblogs.com/huxiaobai/p/11541254.html
Copyright © 2011-2022 走看看