线程间的通讯(wait和notify)

今天学重新学习了进程之间的通讯,还是有所收获。线程之间的通讯有多种方式,在这主要讲的的是synchronized与wait、notify组合使用,来实现线程之间的通讯。首先wait、notify是Object的方法,要使用这两个方法之前,必须获得对象的监视器monitor,所以首先要记住用法:wait和notify必须在synchronized方法块中或者在synchronized方法中。
以下是几个比较典型的例子了,都是自己侧过的,能正常运行出正确结果,有些题是面试题。

1、两个线程,子线程先执行10次,接着主线程执行100次,以此重复100次。
/**
首先分析一下题目,一些初学者可能会误以为线程执行10次,是不是线程被调用了10次,认为是执行了10次run()或者调用了线程的10次.start();执行10次其实就是循环执行10次run()方法体中做的事情,可以用循环for或者while()来实现,如:
....
    run(){
        for(int i = 0; i < 10 ; i++){
            businessAction....
        }
    }
这个就相当于线程执行了10次,are you 明白?
接下来就是代码实现.
public class MainAndSubThread {
    //相当于线程间的通讯器
    public static boolean beShouldSub =true;
    /**这是一个内部类,和成员变量一样,可以用public,private等修饰,这个要注意在面试宝典中有个提说的是一个java文件中只能有一个public class 类,而且必须与文件名相同,注意区分。
    */
    private class BussinessThread{
        //主线程要做的事情
        public synchronized void main_thread(int i){
            try {
                while(beShouldSub){
                    this.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for(int j =0; j < 100; j++){
                System.out.println(Thread.currentThread().getName()+"-loop-"+i+"----times "+j);
            }
            this.notify();
            beShouldSub =true;

        }
        //子线程要做的事情
        public synchronized void sub_thread(int i){
            try {
                while(!beShouldSub){
                    this.wait();
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            for(int j = 0; j < 10; j++){
                System.out.println(Thread.currentThread().getName()+"-loop-"+i+"----times "+j);
            }
            this.notify();
            beShouldSub =false;
        }
    }
    public static void main(String[] args){
         final BussinessThread  biz = new MainAndSubThread().new BussinessThread();
        new Thread(new Runnable() {
            @Override
            public void run() {
                //子线程
                for(int i =0; i < 50; i++){
                    biz.sub_thread(i);
                }
            }
        }).start();
        //主线程
        for(int i = 0; i < 50; i++){
            biz.main_thread(i);
        }
    }
}
....
*/
2.用线程间的通讯,控制线程的执行顺序。
2.1简单版:3个线程A线程打印A,B线程打印B,C线程打印C
public class MyThreadFactory0 {
    private boolean isThread_A_Waiting;  
    private boolean isThread_B_Waiting;  
    private boolean isThread_C_Waiting;
    public MyThreadFactory0(){
        isThread_A_Waiting = true;
        isThread_B_Waiting =true;
        isThread_C_Waiting =true;
    }
    /**
     * 锁对象
     */
    private final Object object = new Object();
    /*
     * mian()
     */
    public static void main(String[] args){
        MyThreadFactory0 mt = new MyThreadFactory0();
        mt.startThreadA();
        mt.startThreadB();
        mt.startThreadC();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        mt.startFristThread();
    }
    public void startFristThread(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object) {
                    System.out.println("唤醒线程开始执行");
                    //首先释放A线程
                    wakeUp_A();
                }
            }
        }).start();
    }
    public void startThreadA(){
        new Thread(new Runnable(){
            @Override
            public void run(){
                //A线程
                System.out.println("Thread-A 开始等待.....");
                synchronized (object) {
                        try {
                            while(isThread_A_Waiting){
                                object.wait();
                            }//while
                        } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                            e.printStackTrace();
                            }
                            System.out.println("Thread-A 执行结束...");
                            try {
                                Thread.sleep(2000);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            wakeUp_B();
                }//synchronized
            }
        }).start();
    }
    public void startThreadB(){
        new Thread(new Runnable(){
            @Override
            public void run(){
                //线程B
                System.out.println("Thread-B 开始等待.....");
                synchronized (object) {
                        try {
                            while(isThread_B_Waiting){
                                object.wait();
                            }
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println("Thread-B 执行结束....");
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        wakeUp_C();
                }//cynchronized
            }

        }).start();
    }
    public void startThreadC(){
        new Thread(new Runnable(){
            @Override
            public void run(){
                //线程C
                System.out.println("Thread-C 开始等待.....");
                synchronized (object) {
                        try {
                            while(isThread_C_Waiting){
                                object.wait();
                            }
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println("Thread-C 执行结束....");
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println("All thread finished.......");
                }//synchronized
            }
        }).start();
    }
    /**
     * 唤醒A线程
     */
    protected void wakeUp_A() {
        isThread_A_Waiting =false;
        object.notify();
    }
    /**
     * 唤醒B线程
     */
    protected void wakeUp_B() {
        isThread_B_Waiting =false;
        object.notify();
    }
    /**
     * 唤醒C线程
     */
    protected void wakeUp_C() {
        isThread_C_Waiting =false;
        object.notify();
    }
}
程序执行结果:
![这里写图片描述](http://img.blog.csdn.net/20170610143906375?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHVvc2gxMjM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
2.2、加强版 :用3个线程分别打印ABC,A线程打印A,B线程打印B,C线程打印C,依次循环打印10package com.ecc.liana.innermanage.test.thread;

public class MyThreadFactory {
    private boolean isThread_A_Waiting;  
    private boolean isThread_B_Waiting;  
    private boolean isThread_C_Waiting;
    public MyThreadFactory(){
        isThread_A_Waiting = true;
        isThread_B_Waiting =true;
        isThread_C_Waiting =true;
    }
    /**
     * 锁对象
     */
    private final Object object = new Object();
    /*
     * mian()
     */
    public static void main(String[] args){
        MyThreadFactory mt = new MyThreadFactory();
        mt.startThreadA();
        mt.startThreadB();
        mt.startThreadC();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        mt.startFristThread();
    }
    public void startFristThread(){
        new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (object) {
                    System.out.println("唤醒线程开始执行");
                    //首先释放A线程
                    wakeUp_A();
                }
            }
        }).start();
    }
    public void startThreadA(){
        new Thread(new Runnable(){
            @Override
            public void run(){
                //A线程
                System.out.println("Thread-A 开始等待.....");
                synchronized (object) {
                    for(int i = 0; i < 10 ;i++){
                        try {
                            while(isThread_A_Waiting){
                                object.wait();
                            }//while
                        } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                            e.printStackTrace();
                            }
                            System.out.println("Thread-A 执行结束...");
                            try {
                                Thread.sleep(2000);
                            } catch (InterruptedException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                            wakeUp_B();
                    }
                }//synchronized
            }
        }).start();
    }
    public void startThreadB(){
        new Thread(new Runnable(){
            @Override
            public void run(){
                //线程B
                System.out.println("Thread-B 开始等待.....");
                synchronized (object) {
                    for (int i = 0; i < 10; i++) {
                        try {
                            while(isThread_B_Waiting){
                                object.wait();
                            }
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println("Thread-B 执行结束....");
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        wakeUp_C();
                    }
                }//cynchronized
            }

        }).start();
    }
    public void startThreadC(){
        new Thread(new Runnable(){
            @Override
            public void run(){
                //线程C
                System.out.println("Thread-C 开始等待.....");
                synchronized (object) {
                    for(int i = 0; i < 10; i++){
                        try {
                            while(isThread_C_Waiting){
                                object.wait();
                            }
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        System.out.println("Thread-C 执行结束....");
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                        //System.out.println("All thread finished.......");
                        wakeUp_A();
                    }
                }//synchronized
            }
        }).start();
    }
    /**
     * 唤醒A线程
     */
    protected void wakeUp_A() {
        isThread_A_Waiting =false;
        isThread_B_Waiting =true;
        isThread_C_Waiting =true;
        object.notify();
    }
    /**
     * 唤醒B线程
     */
    protected void wakeUp_B() {
        isThread_A_Waiting =true;
        isThread_B_Waiting =false;
        isThread_C_Waiting =true;
        object.notify();
    }
    /**
     * 唤醒C线程
     */
    protected void wakeUp_C() {
        isThread_A_Waiting =true;
        isThread_B_Waiting =true;
        isThread_C_Waiting =false;
        object.notify();
    }
}
执行结果:
Thread-A 开始等待.....
Thread-B 开始等待.....
Thread-C 开始等待.....
唤醒线程开始执行
Thread-A 执行结束...
Thread-B 执行结束....
Thread-C 执行结束....
Thread-A 执行结束...
Thread-B 执行结束....
Thread-C 执行结束....
Thread-A 执行结束...
Thread-B 执行结束....
Thread-C 执行结束....
Thread-A 执行结束...
Thread-B 执行结束....
Thread-C 执行结束....
Thread-A 执行结束...
Thread-B 执行结束....
Thread-C 执行结束....
Thread-A 执行结束...
已标记关键词 清除标记
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页