线程间的通信------------等待唤醒机制

来源:互联网 发布:农村淘宝招聘司机吗 编辑:程序博客网 时间:2024/05/21 14:44
线程间的通信
同步线程必须满足两个条件:
一:两个或两个以上的线程
二:都使用同一个锁对象


题目描述:
       首先有一个资源池(Resource),输入线程(Input)不断往资源池内添加内容,输出线程(Output)不断往外输出内容
       并且两个线程需要同步。需要的结果是,输入线程输入一个内容,然后立马输出线程读出一个内容。

第一次编写代码,不使用同步,也不是用等待唤醒机制

/** *线程间的通信:--------等待唤醒机制 *题目描述: *      首先由一个资源池(Resource),输入线程(Input)不断往资源池内添加内容,输出线程(Output)不断往外输出内容 *      并且两个线程需要同步 *  * */class Resource{String name;String sex;}class Input implements Runnable{boolean inputflag=false;Resource r;Input(Resource r){this.r = r;}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){if(inputflag){r.name = "mike";r.sex = "man";inputflag = false;}else {r.name = "丽丽";r.sex = "女";inputflag = true;}}}}class Output implements Runnable{Resource r;public Output(Resource r){this.r = r;}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){System.out.println(r.name+"-----"+r.sex);}}}public class ThreadSynchronized {public static void main(String[] args) {// TODO Auto-generated method stubResource 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();}}


出现上面情况,“mike------女”和“丽丽------man”明显感觉到很奇怪
解释原因:输入线程没有对输入完成的时候,输出线程就抢占了cpu,直接执行输出线程,因此才会有以上的奇怪现象
解决方案:加入线程同步,使输入线程和输出线程同步。对资源的操作时候就只有输入线程完成赋值后输出线程有能执行

加入线程同步块后的代码如下:


/* 线程间的通信:--------等待唤醒机制 题目描述:       首先由一个资源池(Resource),输入线程(Input)不断往资源池内添加内容,输出线程(Output)不断往外输出内容       并且两个线程需要同步   * */class Resource{String name;String sex;//boolean flag = false;  //该标记初始为false}class Input implements Runnable{boolean inputflag=false;Resource r;Input(Resource r){this.r = r;}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){synchronized (r) {         //该地方必须加同步块if(inputflag){r.name = "mike";r.sex = "man";inputflag = false;}else {r.name = "丽丽";r.sex = "女";inputflag = true;}}}}}class Output implements Runnable{Resource r;public Output(Resource r){this.r = r;}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){synchronized (r) {    //这个地方锁的对象一定要和上面同步块的锁对象一致,不一致就不满足同步条件System.out.println(r.name+"-----"+r.sex);}}}}public class ThreadSynchronized {public static void main(String[] args) {// TODO Auto-generated method stubResource 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();}}



但是问题又出现了,出现的全部是一样的结构,安装预期的应该是,一个“mike-----man”然后一个“丽丽------女”。但是为什么会出现这种情况呢?
这是由于输入线程获得cpu以后,多次赋值,等到输出线程获得cpu的时候就会一次输出好多的同样数据
解决方案:加入等待唤醒机制

/* 线程间的通信:--------等待唤醒机制 题目描述:       首先有一个资源池(Resource),输入线程(Input)不断往资源池内添加内容,输出线程(Output)不断往外输出内容       并且两个线程需要同步   * */class Resource{String name;String sex;boolean flag = false;  //该标记初始为false}class Input implements Runnable{boolean inputflag=false;Resource r;Input(Resource r){this.r = r;}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){if(r.flag)   //如果标记位为false则让线程进入后面的同步块,如果为true则让该线程等待try{ r.wait();}catch(Exception e){};synchronized (r) {         //该地方必须加同步块if(inputflag){r.name = "mike";r.sex = "man";inputflag = false;}else {r.name = "丽丽";r.sex = "女";inputflag = true;}r.flag = true;//唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程r.notify();  //即也就是唤醒output线程}}}}class Output implements Runnable{Resource r;public Output(Resource r){this.r = r;}@Overridepublic void run() {// TODO Auto-generated method stubwhile(true){synchronized (r) {    //这个地方锁的对象一定要和上面同步块的锁对象一致,不一致就不满足同步条件if(!r.flag)try{ r.wait();}catch(Exception e){};System.out.println(r.name+"-----"+r.sex);r.flag = false;r.notify();}}}}public class ThreadSynchronized {public static void main(String[] args) {// TODO Auto-generated method stubResource 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();}}


最后可以看出,得出了我想要的结果




























0 0
原创粉丝点击