3.6 线程通信

       线程通信是指不同线程之间相互传递信息。线程通信可以实现线程等待其他线程执行结果后再执行,这样来实现不同线程之间按照有序的方式进行工作。

       那么问题来了,Java要如何实现线程间通信呢?

3.6 线程通信_两个线程一个输出奇数一个偶数



3.6.1 实现通信–共享变量

       可以通过共享变量来实现,实现思路就是一个通过一个共享变量状态的改变来实现线程通信。下边就从代码来看下。

3.6 线程通信_线程通信实现_02

public class SignalDemo {
//    private Object obj = new Object();
    boolean singal = false;
    public boolean isSingal() {
        return singal;
    }
    public void setSingal(boolean singal) {
        this.singal = singal;
    }
    public static void main(String[] args) {
        SignalDemo signalDemo = new SignalDemo();
        new Thread(()->{
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            signalDemo.setSingal(true);
            System.err.println("\r\n线程2修改信号值");
        }).start();

        while (!signalDemo.isSingal()){
            System.err.print("k");
        }
    }
}

3.6 线程通信_两个线程一个输出奇数一个偶数_03


       上例实现的就是一个线程工作,然后另一个线程通过改变共享变量来终止工作线程,Just it!


3.6.2 wait-notify机制

       官方注释:wait方法可以使当前线程进入等待直到其他线程调用了对象的notify或者notifyAll方法。该方法本质上调用的是wait(0).

* Causes the current thread to wait until another thread invokes the
 * {@link java.lang.Object#notify()} method or the
 * {@link java.lang.Object#notifyAll()} method for this object.
 * In other words, this method behaves exactly as if it simply
 * performs the call {@code wait(0)}.

       现在了解了wait-notify的机制后看一个小demo。用两个线程一个线程输出0-100以内的奇数,一个线程输出0-100以内的偶数。

class SignalDemo2{
    Object myMonitorObject = new Object();

    public void doWait(){
        synchronized(myMonitorObject){
            try{
                myMonitorObject.wait();
            } catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }

    public void doNotify(){
        synchronized(myMonitorObject){
            myMonitorObject.notify();
        }
    }

    public static void main(String[] args) {
        Object o = new Object();
        AtomicInteger i= new AtomicInteger();
        new Thread(()->{
            synchronized (o){
                while (i.get() <=100){
                    if (i.get() %2==0) {
                        System.err.println(Thread.currentThread() + ":" + i);
                        i.getAndIncrement();
                        try {
                            o.wait();
                            o.notify();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();

        new Thread(()->{
            synchronized (o){
                while (i.get() <=100){
                    if (i.get() %2!=0) {
                        System.err.println(Thread.currentThread() + ":" + i);
                        i.getAndIncrement();
                        try {
                            o.notify();
                            o.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }).start();
    }
}

       该实现原理非常简单,当一个线程输出奇数或者偶数后,就使当前线程进入等待状态,并且通知对方操作。 注意:当使用wait-notify机制的时候不要使用String对象或者全局变量的wait方法,可能会由于String常量引用导致意想不到的结果。