多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
[TOC] # 简介 多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同。通过一定的手段使各个线程能有效的利用资源。而这种手段即—— 等待唤醒机制。 等待唤醒机制所涉及到的方法: * wait() :等待,将正在执行的线程释放其执行资格 和 执行权,并存储到线程池中。 * notify():唤醒,唤醒线程池中被wait()的线程,一次唤醒一个,而且是任意的。 * notifyAll(): 唤醒全部:可以将线程池中的所有wait() 线程都唤醒。 其实,所谓唤醒的意思就是让 线程池中的线程具备执行资格。必须注意的是,这些方法都是在 同步中才有效。同时这些方法在使用时必须标明所属锁,这样才可以明确出这些方法操作的到底是哪个锁上的线程。 仔细查看JavaAPI之后,发现这些方法 并不定义在 Thread中,也没定义在Runnable接口中,却被定义在了Object类中,为什么这些操作线程的方法定义在Object类中? 因为这些方法在使用时,必须要标明所属的锁,而锁又可以是任意对象。能被任意对象调用的方法一定定义在Object类中。 ![](https://box.kancloud.cn/45c29a075f8cd79b8ac55bf59d51d0df_1950x356.jpg) # 例子 ![](https://box.kancloud.cn/c97a360b51327187161cbb6a05c2bef0_1376x512.jpg) 如上图说示,输入线程向Resource中输入name ,sex , 输出线程从资源中输出,先要完成的任务是: * 1.当input发现Resource中没有数据时,开始输入,输入完成后,叫output来输出。如果发现有数据,就wait(); * 2.当output发现Resource中没有数据时,就wait() ;当发现有数据时,就输出,然后,叫醒input来输入数据。 那个对象等待的就用那个对象唤醒 下面代码,模拟等待唤醒机制的实现 * 模拟资源类 ~~~ public class Resource { private String name; private String sex; private boolean flag = false; public synchronized void set(String name, String sex) { if (flag) try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } // 设置成员变量 this.name = name; this.sex = sex; // 设置之后,Resource中有值,将标记该为 true , flag = true; // 唤醒output this.notify(); } public synchronized void out() { if (!flag) try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } // 输出线程将数据输出 System.out.println("姓名: " + name + ",性别: " + sex); // 改变标记,以便输入线程输入数据 flag = false; // 唤醒input,进行数据输入 this.notify(); } } ~~~ * 输入线程任务类 ~~~ public class Input implements Runnable { private Resource r; public Input(Resource r) { this.r = r; } @Override public void run() { int count = 0; while (true) { if (count == 0) { r.set("小明", "男生"); } else { r.set("小花", "女生"); } // 在两个数据之间进行切换 count = (count + 1) % 2; } } } ~~~ * 输出线程任务类 ~~~ public class Output implements Runnable { private Resource r; public Output(Resource r) { this.r = r; } @Override public void run() { while (true) { r.out(); } } } ~~~ * 测试类 ~~~ public class ResourceDemo { public static void main(String[] args) { // 资源对象 Resource r = new Resource(); // 任务对象 Input in = new Input(r); Output out = new Output(r); // 线程对象 Thread t1 = new Thread(in); Thread t2 = new Thread(out); // 开启线程 t1.start(); t2.start(); } } ~~~