java线程间协作的另一种方式——await()、signal()、signalAll()

本文主要参考:

《Think in java》

ExecutorService中有一ReentrantLock,可以使用这个锁,同时还有对应的这个await()方法。
使用这种方法的时候必须使用ExecutorService。
我们还是以先扫地,再拖地的这个为例。

首先创建调度器类:

package com.xueyou.demo.threadcooperateexecutorservice;

import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class SweepAndMopDispacherNew {
    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();
    private boolean isSweeping = false;

    public void sweeped() {
        lock.lock();
        try {
            isSweeping = true;
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public synchronized void Mopped() {
        lock.lock();
        try {
            isSweeping = false;
            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    public void waitForSweeped() throws InterruptedException {
        lock.lock();
        try {
            while (isSweeping == false) {
                condition.await();
            }
        } finally {
            lock.unlock();
        }
    }

    public void waitForMopped() throws InterruptedException {
        lock.lock();
        try {
            while (isSweeping == true) {
                condition.await();
            }
        } finally {
            lock.unlock();
        }
    }
}
2、然后分别创建扫地和拖地线程。
package com.xueyou.demo.threadcooperateexecutorservice;

import java.util.concurrent.TimeUnit;

public class SweepRunner implements Runnable {
    private SweepAndMopDispacherNew dispacher;

    public SweepRunner(SweepAndMopDispacherNew 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.threadcooperateexecutorservice;

import java.util.concurrent.TimeUnit;

public class MopRunner implements Runnable {
    private SweepAndMopDispacherNew dispacher;

    public MopRunner(SweepAndMopDispacherNew 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.threadcooperateexecutorservice;

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

public class TestMain {
    public static void main(String[] args) {
        SweepAndMopDispacherNew dispacher = new SweepAndMopDispacherNew();
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(new SweepRunner(dispacher));
        executorService.submit(new MopRunner(dispacher));
        try {
            TimeUnit.SECONDS.sleep(5);
            executorService.shutdownNow();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
4、测试运行结果如下:


猜你喜欢

转载自blog.csdn.net/wild46cat/article/details/80808897
今日推荐