JUC(十一):线程按序交替

原创文章,转载请注明原文章地址,谢谢!

在前面我们说到线程通信Condition,其作用是在于对锁进行了精确的控制。它和Object中的等待唤醒机制不同的是,Object中的wait()、notify()、notifyAll()方法是和"同步锁"(synchronized关键字)捆绑使用的,而Condition是需要与"互斥锁"/"共享锁"捆绑使用的。

但是Condition除了支持上面的功能之外,它更强大的地方在于,能够更加精细的控制多线程的休眠与唤醒。对于同一个锁,我们可以创建多个Condition,在不同的情况下使用不同的Condition。下面我们就举一个例子,来演示Condition的这一特点。

示例

编写一个程序,开启3个线程,这三个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要
求输出的结果必须按顺序显示。如:ABCABCABC…… 依次递归。

public class AlternateDemo {

    //当前正在执行线程的标记
    private int number = 1;

    private Lock lock = new ReentrantLock();
    private Condition condition1 = lock.newCondition();
    private Condition condition2 = lock.newCondition();
    private Condition condition3 = lock.newCondition();

    public void loopA(int totalLoop) {
        lock.lock();
        try {
            if (number != 1) {
                condition1.await();
            }
            for (int i = 1; i <= 1; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
            }
            number = 2;
            condition2.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void loopB(int totalLoop) {
        lock.lock();
        try {
            if (number != 2) {
                condition2.await();
            }
            for (int i = 1; i <= 1; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
            }
            number = 3;
            condition3.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void loopC(int totalLoop) {
        lock.lock();
        try {
            if (number != 3) {
                condition3.await();
            }
            for (int i = 1; i <= 1; i++) {
                System.out.println(Thread.currentThread().getName() + "\t" + i + "\t" + totalLoop);
            }
            number = 1;
            condition1.signal();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }
}
public class AlternateTest {

    public static void main(String[] args) {
        AlternateDemo ad = new AlternateDemo();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 20; i++) {
                    ad.loopA(i);
                }
            }
        }, "A").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 20; i++) {
                    ad.loopB(i);
                }
            }
        }, "B").start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 1; i <= 20; i++) {
                    ad.loopC(i);
                    System.out.println("-----------------------------------");
                }
            }
        }, "C").start();
    }
}

测试结果为

A   1   1
B   1   1
C   1   1
-----------------------------------
A   1   2
B   1   2
C   1   2
-----------------------------------
A   1   4
B   1   4
C   1   4
-----------------------------------
......
-----------------------------------
A   1   20
B   1   20
C   1   20
-----------------------------------

博客内容仅供自已学习以及学习过程的记录,如有侵权,请联系我删除,谢谢!

你可能感兴趣的:(JUC(十一):线程按序交替)