java线程间协作——wait()、notify()、notifyAll()

本文主要介绍进程间的协作。
经常会有一个这样的问题,就是两个线程交替进行执行,当一个线程执行完成后,再执行另一个线程。
那么现在我尝试些一个这样的程序:
先扫地,再拖地,一直循环下去。

1、先写一个控制扫地和拖地的调度器。

package com.xueyou.demo.threadcoopreate;

public class SweepAndMopDispacher {
    private boolean isSweeping = false;

    public synchronized void sweeped() {
        isSweeping = true;
        notifyAll();
    }

    public synchronized void Mopped() {
        isSweeping = false;
        notifyAll();
    }

    public synchronized void waitForSweeped() throws InterruptedException {
        while (isSweeping == false) {
            wait();
        }
    }

    public synchronized void waitForMopped() throws InterruptedException {
        while (isSweeping == true) {
            wait();
        }
    }
}
2、然后分别写拖地和扫地的逻辑。


package com.xueyou.demo.threadcoopreate;

import java.util.concurrent.TimeUnit;

public class SweepRunner implements Runnable {
    private SweepAndMopDispacher dispacher;

    public SweepRunner(SweepAndMopDispacher dispacher) {
        this.dispacher = dispacher;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                System.out.println(Thread.currentThread().getName() + "扫地..");
                TimeUnit.MILLISECONDS.sleep(800);
                dispacher.sweeped();
                dispacher.waitForMopped();
            }
        } catch (InterruptedException e) {
            System.out.println("exit by interrupted");
        } finally {
            System.out.println("mop exit;");
        }
    }
}


package com.xueyou.demo.threadcoopreate;

import sun.util.locale.provider.TimeZoneNameUtility;

import java.util.concurrent.TimeUnit;

public class MopRunner implements Runnable {
    private SweepAndMopDispacher dispacher;

    public MopRunner(SweepAndMopDispacher dispacher) {
        this.dispacher = dispacher;
    }

    @Override
    public void run() {
        try {
            while (!Thread.interrupted()) {
                System.out.println(Thread.currentThread().getName() + "拖地..");
                TimeUnit.MILLISECONDS.sleep(800);
                dispacher.Mopped();
                dispacher.waitForSweeped();
            }
        } catch (InterruptedException e) {
            System.out.println("exit by interrupted");
        } finally {
            System.out.println("Mop runner exit;");
        }
    }
}
3、编写一个测试程序进行测试
package com.xueyou.demo.threadcoopreate;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


public class TestMain {
    public static void main(String[] args) {
        SweepAndMopDispacher dispacher = new SweepAndMopDispacher();
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(new SweepRunner(dispacher));
        executorService.submit(new MopRunner(dispacher));
        try {
            TimeUnit.SECONDS.sleep(4);
            executorService.shutdownNow();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

运行结果:


需要注意的是这里面的结束是通过shutodownNow()实现的。
而在每个实现的Runnable的接口里面也是通过捕获interrupted状态或者异常来实现结束的。


猜你喜欢

转载自blog.csdn.net/wild46cat/article/details/80808645