一 .概述
当我们实现了原子性操作的时候,我们又会遇到一个问题,那就是线程之间通信的问题.所谓的线程通信,指的就是线程间的执行顺序是需要进行一定的控制的.
我们拿最经典的生产者和消费者模型进行说明:
private static Object lock = new Object(); private static int index = 1; private static volatile Boolean flag = true; /** * 生产者的线程 */ static class Provider { public static void proIndex() { synchronized (lock) { if (!flag) { System.out.println(Thread.currentThread().getName() + "--" + index++); lock.notify(); flag = !flag; } else { try { lock.wait(); } catch (InterruptedException e1) { e1.printStackTrace(); } } } } } /** * 消费者的线程 */ static class Consumer { public static void conIndex() { synchronized (lock) { if (flag) { System.out.println(Thread.currentThread().getName() + "--" + index); lock.notify(); flag = !flag; } else { try { lock.wait(); } catch (InterruptedException e1) { e1.printStackTrace(); } } } } } public static void main(String[] args) throws InterruptedException { new Thread(() -> { while (true) { sleep(); Provider.proIndex(); } }).start(); new Thread(() -> { while (true) { sleep(); Consumer.conIndex(); } }).start(); } private static void sleep() { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } }
在这里,我们使用wait()和notify()方法进行实现.
但是我们发现了一个问题,如果我们实现线程之间的通讯的代价实在是太高了.
于是在并发包之中为我们提供了一系列的线程通讯的工具,这些都会在后面进行分析.