多线程进阶之等待唤醒机制
Posted zjm1999
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多线程进阶之等待唤醒机制相关的知识,希望对你有一定的参考价值。
/* * 线程间通讯实例 * 多个线程在处理同一资源,但是任务不同 */ //资源 class Resource { String name; String sex; } //输入 class Input implements Runnable { Resource r;//类对象 public Input(Resource r)//类对象做构造参数-->初始化资源 { this.r=r; } public void run() { int x=0; while(true) { /* * 加上同步锁,因为输入输出任务共享资源,所以将资源对象r作为锁 * 也是为了让输入输出处于同一同步锁中,这样输入就不会在输入姓名林玲还没有赋值完性别女 * 时(周俊明被林玲覆盖),切换执行权 */ synchronized(r) { if(x==0) { r.name="周俊明"; r.sex="男"; } else { r.name="林玲"; r.sex="女"; } } x=(x+1)%2;//算法切换:不断由if和else切换 } } } //输出 class Output implements Runnable { Resource r; public Output(Resource r) { this.r=r; } public void run() { while(true) { synchronized(r) { System.out.println(r.name+"....."+r.sex); } } } } 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(); } }
变身 :
/** * 等待/唤醒机制 * * 涉及的方法: * * 1.wait():让线程处于冻结状态,被wait的线程会被存储到线程池中. * 2.notify():唤醒线程池中的一个线程(任意) * 3.notifyAll():唤醒线程池中的索引线程. * * 这些方法都必须定义在同步中 * 因为这些方法是用于操作线程状态的方法 * 必须要明确到底操作的是哪个锁上的线程 * * 为什么操作线程的方法wait notify notifyAll定义在Object类中 * * 因为这些方法是监视器的方法.监视器就是锁 * 锁可以是任意的对象,任意的对象调用的方式一定定义在object类中 * */ //资源 class Resour { String name; String sex; boolean flag=false;//标记 } //输入 class Inputs implements Runnable { Resour r;//类对象 public Inputs(Resour r)//类对象做构造参数-->初始化资源 { this.r=r; } public void run() { int x=0; while(true) { /* * 加上同步锁,因为输入输出任务共享资源,所以将资源对象r作为锁 * 也是为了让输入输出处于同一同步锁中,这样输入就不会在输入姓名林玲还没有赋值完性别女 * 时(周俊明被林玲覆盖),切换执行权 */ synchronized(r) { try { if(r.flag) r.wait(); //标明睡眠/唤醒同一锁上线程 } catch (InterruptedException e) { // TODO: handle exception } if(x==0) { r.name="周俊明"; r.sex="男"; } else { r.name="林玲"; r.sex="女"; } r.flag=true; r.notify(); } x=(x+1)%2;//算法切换:不断由if和else切换 } } } //输出 class Outputs implements Runnable { Resour r; public Outputs(Resour r) { this.r=r; } public void run() { while(true) { synchronized(r) { try { if(!r.flag) r.wait(); } catch (InterruptedException e) { } System.out.println(r.name+"....."+r.sex); r.flag=false; r.notify(); } } } } public class ResourceDemo1 { public static void main(String[] args) { //创建资源 Resour r=new Resour(); //创建任务 Inputs in=new Inputs(r); Outputs out=new Outputs(r); //创建线程 Thread t1=new Thread(in); Thread t2=new Thread(out); t1.start(); t2.start(); } }
优化:
//资源 class Resours { private String name;//资源私有 private String sex; private boolean flag=false;//标记 public synchronized void set(String name,String sex) { if(flag) try {this.wait();} catch (InterruptedException e) {} //标明睡眠/唤醒同一锁上线程 this.name=name; this.sex=sex; flag=true; this.notify(); } public synchronized void out() { if(!flag) try {this.wait();} catch (InterruptedException e) {} System.out.println(name+"..."+sex); flag=false; this.notify(); } } //输入 class Inputce implements Runnable { Resours r;//类对象 public Inputce(Resours r)//类对象做构造参数-->初始化资源 { this.r=r; } public void run() { int x=0; while(true) { /* * 加上同步锁,因为输入输出任务共享资源,所以将资源对象r作为锁 * 也是为了让输入输出处于同一同步锁中,这样输入就不会在输入姓名林玲还没有赋值完性别女 * 时(周俊明被林玲覆盖),切换执行权 */ if(x==0) { r.set("周俊明","男"); } else { r.set("林玲","女"); } x=(x+1)%2;//算法切换:不断由if和else切换 } } } //输出 class Outputce implements Runnable { Resours r; public Outputce(Resours r) { this.r=r; } public void run() { while(true) { r.out(); } } } public class ResourceDemo2 { public static void main(String[] args) { //创建资源 Resours r=new Resours(); //创建任务 Inputce in=new Inputce(r); Outputce out=new Outputce(r); //创建线程 Thread t1=new Thread(in); Thread t2=new Thread(out); t1.start(); t2.start(); } }
一不小心就暴露了真实姓名
以上是关于多线程进阶之等待唤醒机制的主要内容,如果未能解决你的问题,请参考以下文章