标签:style blog http color io ar java strong 数据
一、线程间的通信
实例代码:
需求是:输入一个姓名和性别后,就输出一个姓名和性别
class Resource { String name; String sex ; } class Input implements Runnable { Resource r; Input(Resource r) { this.r = r; } public void run() { int x = 0; while(true) { synchronized (r) { if(x==0) { r.name = "BLF"; r.sex = "male"; } else { r.name = "妮妮妮妮"; r.sex = "female"; } x = (++x)%2; } } } } class Output implements Runnable { Resource r; public Output(Resource r) { // TODO Auto-generated constructor stub this.r = r; } public void run() { while(true) { synchronized (r) //输入和输出都是应用同一个锁 { System.out.println(r.name+"..."+r.sex); } } } } public class Main { 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(); } }
二、线程的等待/唤醒机制:
用一个boolean值判断是否有数据,有就不放,没有就放
输入线程执行时判断是否有数据,有,就释放执行权,再释放执行资格,进入冻结状态,输出线程执行,输出后boolean值置为false
Input: if(flag)//有值 wait();//当前冻结,切换输出线程 flag = true; notify(); Output: if(!flag) wait(); flag = false;//flag置为假,输出完毕 notify();//唤醒输入线程
方法:
1.wait();//使线程进入冻结状态,CPU释放执行权和执行资格,被wait()的线程会被存储到线程池中 2.notify();//唤醒线程池中的任意的一个线程 3.notifyAll();//唤醒所有线程,使之处于运行状态或临时阻塞状态,总之,使其具备执行资格
(wait()A锁的线程,只能用A锁的notify唤醒A锁的线程。)
了解:而wait()等方法是定义在Object类中的,这些方法是监视器的方法,而监视器呢,就可以理解为锁,控制哪个锁所属下的线程,而锁又可以是任意的,而所有的类都是继承于Object类的,所以wait()等类是定义在Object里
下述代码就解决了上述代码的问题,实现了输入输出线程的交替执行
class Resource extends Object { String name; String sex ; boolean flag = false; } class Input implements Runnable { Resource r; Input(Resource r) { this.r = r; } public void run() { int x = 0; while(true) { synchronized (r) { if(r.flag) { try { r.wait(); } catch (Exception e) { // TODO: handle exception } } if(x==0) { r.name = "BLF"; r.sex = "male"; } else { r.name = "妮妮妮妮"; r.sex = "female"; } r.flag = true; r.notify(); x = (++x)%2; } } } } class Output implements Runnable { Resource r; public Output(Resource r) { // TODO Auto-generated constructor stub this.r = r; } public void run() { while(true) { synchronized (r) { if(!r.flag) { try { r.wait(); } catch (Exception e) { // TODO: handle exception } } System.out.println(r.name+"..."+r.sex); r.flag = false; r.notify(); } } } } public class Main { 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(); } }
资源中的成员为了可控,应该为私有的,对外提供方法
所以同步的操作,就在Resource类中执行,应用同步函数
class Resource extends Object { private String name; private String sex ; private boolean flag = false; public synchronized void set(String name,String sex) { // TODO Auto-generated constructor stub if(flag) { try { this.wait(); } catch (Exception e) { // TODO: handle exception } } this.name = name; this.sex = sex; flag = true; this.notify(); } public synchronized void out() { if(!flag) { try { this.wait(); } catch (Exception e) { // TODO: handle exception } System.out.println(name+" : "+sex); flag = false; this.notify(); } } } class Input implements Runnable { Resource r; Input(Resource r) { this.r = r; } public void run() { int x = 0; while(true) { if(x==0) { r.set("BLF", "male"); } else { r.set("妮妮妮妮", "female"); } x = (++x)%2; } } } class Output implements Runnable { Resource r; public Output(Resource r) { // TODO Auto-generated constructor stub this.r = r; } public void run() { while(true) { r.out(); } } } public class Main { 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(); } }
JAVA学习第二十六课(多线程(五))- 多线程间的通信问题
标签:style blog http color io ar java strong 数据
原文地址:http://blog.csdn.net/wjw0130/article/details/39959445