标题
概述
1.Condition简单使用
2.Condition生产者消费者模型
第1节 Condition简单使用
Condition使用方式如下。
public class ConditionDemo {
/**
* 获取独占锁
*/
private ReentrantLock lock = new ReentrantLock();
/**
* 获取条件1
*/
private Condition condition1 = lock.newCondition();
/**
* 获取条件2
*/
private Condition condition2 = lock.newCondition();
/**
* 获取条件3
*/
private Condition condition3 = lock.newCondition();
/**
* 日期格式化
*/
private SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:MM:ss");
public static void main(String[] args) throws InterruptedException {
ConditionDemo conditionDemo = new ConditionDemo();
// Alibaba Java Coding Guidelines plugin 插件提示不要直接使用Executors
ExecutorService executorService = Executors.newCachedThreadPool();
Thread1 thread1 = conditionDemo.new Thread1();
Thread2 thread2 = conditionDemo.new Thread2();
Thread3 thread3 = conditionDemo.new Thread3();
// 启动线程任务1、2、3.
executorService.execute(thread1);
executorService.execute(thread2);
executorService.execute(thread3);
Thread.sleep(2000);
// 依次唤醒各线程任务.
signalTest(conditionDemo);
executorService.shutdown();
}
/**
* 依次唤醒各线程任务,以观察condition的作用
*
* @param conditionDemo ConditionDemo对象
* @throws InterruptedException 中断异常
*/
public static void signalTest(ConditionDemo conditionDemo) throws InterruptedException {
// 获取独占锁 唤醒condition1的线程
conditionDemo.lock.lock();
conditionDemo.condition1.signal();
// 释放独占锁 等待thread1执行完毕.
conditionDemo.lock.unlock();
Thread.sleep(2000);
// 获取独占锁 唤醒condition2的线程
conditionDemo.lock.lock();
conditionDemo.condition2.signal();
// 释放独占锁 等待thread2执行完毕.
conditionDemo.lock.unlock();
Thread.sleep(2000);
// 获取独占锁 唤醒condition3的线程
conditionDemo.lock.lock();
conditionDemo.condition3.signal();
// 释放独占锁 等待thread2执行完毕.
conditionDemo.lock.unlock();
Thread.sleep(2000);
}
/**
* 线程任务定义类
*/
public class Thread1 implements Runnable {
public Thread1() {
}
@Override
public void run() {
try {
// 设置线程名称
Thread.currentThread().setName(Thread1.class.getSimpleName());
System.out.printf("%s线程启动\n", Thread.currentThread().getName());
lock.lock();
// 在condition1上阻塞,并且释放独占锁lock.
condition1.await();
System.out.printf("%s线程被唤醒", Thread.currentThread().getName());
printDate();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/**
* 线程任务定义类
*/
public class Thread2 implements Runnable {
public Thread2() {
}
@Override
public void run() {
try {
Thread.currentThread().setName(Thread2.class.getSimpleName());
System.out.printf("%s线程启动\n", Thread.currentThread().getName());
lock.lock();
// 在condition2上阻塞,并且释放独占锁lock.
condition2.await();
System.out.printf("%s线程被唤醒", Thread.currentThread().getName());
printDate();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/**
* 线程任务定义类
*/
public class Thread3 implements Runnable {
public Thread3() {
}
@Override
public void run() {
try {
Thread.currentThread().setName(Thread3.class.getSimpleName());
System.out.printf("%s线程启动\n", Thread.currentThread().getName());
lock.lock();
// 在condition2上阻塞,并且释放独占锁lock.
condition3.await();
System.out.printf("%s线程被唤醒", Thread.currentThread().getName());
printDate();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
/**
* 打印时间
*/
void printDate() {
System.out.println("【当前时间:" + simpleDateFormat.format(new Date()) + "】");
}
}
执行以上代码,执行结果如下。
Thread2线程启动
Thread3线程启动
Thread1线程启动
Thread1线程被唤醒【当前时间:2019-11-07 11:11:59】
Thread2线程被唤醒【当前时间:2019-11-07 11:11:01】
Thread3线程被唤醒【当前时间:2019-11-07 11:11:03】
第2节 Condition生产者消费者模型
Condition实现生产者消费者模型如下。
public class ProducerConsumer {
/**
* Lock
*/
private final Lock lock = new ReentrantLock();
/**
* 数组未满
*/
private final Condition notFull = lock.newCondition();
/**
* 数组非空
*/
private final Condition notEmpty = lock.newCondition();
/**
* 存储数据的底层数组
*/
private final Object[] items = new Object[100];
/**
* 输入数据的索引位置
*/
private int inputIndex;
/**
* 输出数据的索引位置
*/
private int outputIndex;
/**
* 计数器
*/
private int count;
/**
* 日期格式化
*/
private static SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:MM:ss SSS");
public static void main(String[] args) {
ExecutorService executorService = null;
try {
// Alibaba Java Coding Guidelines plugin 插件提示不要直接使用Executors
executorService = Executors.newCachedThreadPool();
ProducerConsumer producerConsumer = new ProducerConsumer();
// 10个生产者线程
for (int i = 0; i < 10; i++) {
executorService.submit(() -> {
for (int j = 0; j < 10; j++) {
try {
Thread.sleep(10);
producerConsumer.put(String.format("生产者%s于%s生产一条数据", Thread.currentThread().getName(), printDate()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
// 1个消费者线程
executorService.submit(() -> {
try {
for (int i = 0; i < 100; i++) {
Object outPut = producerConsumer.take();
System.out.printf("消费者获取到数据%s%n", outPut);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
});
} finally {
assert executorService != null;
executorService.shutdown();
}
}
/**
* 生产者方法,往数组里面写数据
*
* @param input 输入数据
* @throws InterruptedException 中断异常
*/
public void put(Object input) throws InterruptedException {
lock.lock();
try {
while (count == items.length) {
//数组已满,没有空间时,挂起等待,直到数组“非满”(notFull)
notFull.await();
}
items[inputIndex] = input;
if (++inputIndex == items.length) {
inputIndex = 0;
}
++count;
// 因为放入了一个数据,数组肯定不是空的了
// 此时唤醒等待这notEmpty条件上的线程
notEmpty.signal();
} finally {
lock.unlock();
}
}
/**
* 消费者方法,从数组里面拿数据
*
* @return 数据
* @throws InterruptedException 中断异常
*/
public Object take() throws InterruptedException {
lock.lock();
try {
while (count == 0) {
// 数组是空的,没有数据可拿时,挂起等待,直到数组非空(notEmpty)
notEmpty.await();
}
Object x = items[outputIndex];
if (++outputIndex == items.length) {
outputIndex = 0;
}
--count;
// 因为拿出了一个数据,数组肯定不是满的了
// 此时唤醒等待这notFull条件上的线程
notFull.signal();
return x;
} finally {
lock.unlock();
}
}
/**
* 打印时间
*/
private static String printDate() {
return "【当前时间:" + simpleDateFormat.format(new Date()) + "】";
}
}
执行以上代码,执行结果如下。
消费者获取到数据生产者pool-1-thread-10于【当前时间:2019-11-07 11:11:19 350】生产一条数据
消费者获取到数据生产者pool-1-thread-1于【当前时间:2019-11-07 11:11:19 348】生产一条数据
消费者获取到数据生产者pool-1-thread-2于【当前时间:2019-11-07 11:11:19 350】生产一条数据
消费者获取到数据生产者pool-1-thread-4于【当前时间:2019-11-07 11:11:19 350】生产一条数据
消费者获取到数据生产者pool-1-thread-9于【当前时间:2019-11-07 11:11:19 350】生产一条数据
消费者获取到数据生产者pool-1-thread-7于【当前时间:2019-11-07 11:11:19 350】生产一条数据
消费者获取到数据生产者pool-1-thread-6于【当前时间:2019-11-07 11:11:19 350】生产一条数据
消费者获取到数据生产者pool-1-thread-8于【当前时间:2019-11-07 11:11:19 350】生产一条数据
消费者获取到数据生产者pool-1-thread-5于【当前时间:2019-11-07 11:11:19 350】生产一条数据
消费者获取到数据生产者pool-1-thread-3于【当前时间:2019-11-07 11:11:19 350】生产一条数据
消费者获取到数据生产者pool-1-thread-10于【当前时间:2019-11-07 11:11:19 363】生产一条数据
消费者获取到数据生产者pool-1-thread-6于【当前时间:2019-11-07 11:11:19 363】生产一条数据
消费者获取到数据生产者pool-1-thread-4于【当前时间:2019-11-07 11:11:19 363】生产一条数据
消费者获取到数据生产者pool-1-thread-5于【当前时间:2019-11-07 11:11:19 363】生产一条数据
消费者获取到数据生产者pool-1-thread-8于【当前时间:2019-11-07 11:11:19 363】生产一条数据
消费者获取到数据生产者pool-1-thread-3于【当前时间:2019-11-07 11:11:19 363】生产一条数据
消费者获取到数据生产者pool-1-thread-1于【当前时间:2019-11-07 11:11:19 363】生产一条数据
消费者获取到数据生产者pool-1-thread-9于【当前时间:2019-11-07 11:11:19 363】生产一条数据
消费者获取到数据生产者pool-1-thread-7于【当前时间:2019-11-07 11:11:19 363】生产一条数据
消费者获取到数据生产者pool-1-thread-2于【当前时间:2019-11-07 11:11:19 363】生产一条数据
消费者获取到数据生产者pool-1-thread-1于【当前时间:2019-11-07 11:11:19 373】生产一条数据
消费者获取到数据生产者pool-1-thread-5于【当前时间:2019-11-07 11:11:19 374】生产一条数据
消费者获取到数据生产者pool-1-thread-9于【当前时间:2019-11-07 11:11:19 374】生产一条数据
消费者获取到数据生产者pool-1-thread-10于【当前时间:2019-11-07 11:11:19 374】生产一条数据
消费者获取到数据生产者pool-1-thread-6于【当前时间:2019-11-07 11:11:19 374】生产一条数据
消费者获取到数据生产者pool-1-thread-4于【当前时间:2019-11-07 11:11:19 374】生产一条数据
消费者获取到数据生产者pool-1-thread-7于【当前时间:2019-11-07 11:11:19 374】生产一条数据
消费者获取到数据生产者pool-1-thread-2于【当前时间:2019-11-07 11:11:19 374】生产一条数据
消费者获取到数据生产者pool-1-thread-8于【当前时间:2019-11-07 11:11:19 374】生产一条数据
消费者获取到数据生产者pool-1-thread-3于【当前时间:2019-11-07 11:11:19 374】生产一条数据
消费者获取到数据生产者pool-1-thread-8于【当前时间:2019-11-07 11:11:19 385】生产一条数据
消费者获取到数据生产者pool-1-thread-1于【当前时间:2019-11-07 11:11:19 385】生产一条数据
消费者获取到数据生产者pool-1-thread-2于【当前时间:2019-11-07 11:11:19 385】生产一条数据
消费者获取到数据生产者pool-1-thread-4于【当前时间:2019-11-07 11:11:19 385】生产一条数据
消费者获取到数据生产者pool-1-thread-9于【当前时间:2019-11-07 11:11:19 385】生产一条数据
消费者获取到数据生产者pool-1-thread-6于【当前时间:2019-11-07 11:11:19 385】生产一条数据
消费者获取到数据生产者pool-1-thread-5于【当前时间:2019-11-07 11:11:19 385】生产一条数据
消费者获取到数据生产者pool-1-thread-3于【当前时间:2019-11-07 11:11:19 385】生产一条数据
消费者获取到数据生产者pool-1-thread-10于【当前时间:2019-11-07 11:11:19 385】生产一条数据
消费者获取到数据生产者pool-1-thread-7于【当前时间:2019-11-07 11:11:19 385】生产一条数据
消费者获取到数据生产者pool-1-thread-1于【当前时间:2019-11-07 11:11:19 395】生产一条数据
消费者获取到数据生产者pool-1-thread-7于【当前时间:2019-11-07 11:11:19 395】生产一条数据
消费者获取到数据生产者pool-1-thread-6于【当前时间:2019-11-07 11:11:19 396】生产一条数据
消费者获取到数据生产者pool-1-thread-2于【当前时间:2019-11-07 11:11:19 396】生产一条数据
消费者获取到数据生产者pool-1-thread-5于【当前时间:2019-11-07 11:11:19 396】生产一条数据
消费者获取到数据生产者pool-1-thread-4于【当前时间:2019-11-07 11:11:19 396】生产一条数据
消费者获取到数据生产者pool-1-thread-8于【当前时间:2019-11-07 11:11:19 396】生产一条数据
消费者获取到数据生产者pool-1-thread-3于【当前时间:2019-11-07 11:11:19 396】生产一条数据
消费者获取到数据生产者pool-1-thread-10于【当前时间:2019-11-07 11:11:19 396】生产一条数据
消费者获取到数据生产者pool-1-thread-9于【当前时间:2019-11-07 11:11:19 396】生产一条数据
消费者获取到数据生产者pool-1-thread-1于【当前时间:2019-11-07 11:11:19 405】生产一条数据
消费者获取到数据生产者pool-1-thread-7于【当前时间:2019-11-07 11:11:19 406】生产一条数据
消费者获取到数据生产者pool-1-thread-5于【当前时间:2019-11-07 11:11:19 406】生产一条数据
消费者获取到数据生产者pool-1-thread-9于【当前时间:2019-11-07 11:11:19 406】生产一条数据
消费者获取到数据生产者pool-1-thread-10于【当前时间:2019-11-07 11:11:19 407】生产一条数据
消费者获取到数据生产者pool-1-thread-2于【当前时间:2019-11-07 11:11:19 407】生产一条数据
消费者获取到数据生产者pool-1-thread-4于【当前时间:2019-11-07 11:11:19 407】生产一条数据
消费者获取到数据生产者pool-1-thread-6于【当前时间:2019-11-07 11:11:19 407】生产一条数据
消费者获取到数据生产者pool-1-thread-8于【当前时间:2019-11-07 11:11:19 407】生产一条数据
消费者获取到数据生产者pool-1-thread-3于【当前时间:2019-11-07 11:11:19 407】生产一条数据
消费者获取到数据生产者pool-1-thread-1于【当前时间:2019-11-07 11:11:19 416】生产一条数据
消费者获取到数据生产者pool-1-thread-5于【当前时间:2019-11-07 11:11:19 417】生产一条数据
消费者获取到数据生产者pool-1-thread-7于【当前时间:2019-11-07 11:11:19 417】生产一条数据
消费者获取到数据生产者pool-1-thread-9于【当前时间:2019-11-07 11:11:19 417】生产一条数据
消费者获取到数据生产者pool-1-thread-10于【当前时间:2019-11-07 11:11:19 417】生产一条数据
消费者获取到数据生产者pool-1-thread-6于【当前时间:2019-11-07 11:11:19 417】生产一条数据
消费者获取到数据生产者pool-1-thread-3于【当前时间:2019-11-07 11:11:19 418】生产一条数据
消费者获取到数据生产者pool-1-thread-8于【当前时间:2019-11-07 11:11:19 420】生产一条数据
消费者获取到数据生产者pool-1-thread-4于【当前时间:2019-11-07 11:11:19 420】生产一条数据
消费者获取到数据生产者pool-1-thread-2于【当前时间:2019-11-07 11:11:19 420】生产一条数据
消费者获取到数据生产者pool-1-thread-9于【当前时间:2019-11-07 11:11:19 428】生产一条数据
消费者获取到数据生产者pool-1-thread-3于【当前时间:2019-11-07 11:11:19 428】生产一条数据
消费者获取到数据生产者pool-1-thread-6于【当前时间:2019-11-07 11:11:19 428】生产一条数据
消费者获取到数据生产者pool-1-thread-1于【当前时间:2019-11-07 11:11:19 429】生产一条数据
消费者获取到数据生产者pool-1-thread-5于【当前时间:2019-11-07 11:11:19 429】生产一条数据
消费者获取到数据生产者pool-1-thread-10于【当前时间:2019-11-07 11:11:19 429】生产一条数据
消费者获取到数据生产者pool-1-thread-7于【当前时间:2019-11-07 11:11:19 430】生产一条数据
消费者获取到数据生产者pool-1-thread-2于【当前时间:2019-11-07 11:11:19 430】生产一条数据
消费者获取到数据生产者pool-1-thread-4于【当前时间:2019-11-07 11:11:19 432】生产一条数据
消费者获取到数据生产者pool-1-thread-8于【当前时间:2019-11-07 11:11:19 432】生产一条数据
消费者获取到数据生产者pool-1-thread-6于【当前时间:2019-11-07 11:11:19 438】生产一条数据
消费者获取到数据生产者pool-1-thread-5于【当前时间:2019-11-07 11:11:19 439】生产一条数据
消费者获取到数据生产者pool-1-thread-10于【当前时间:2019-11-07 11:11:19 440】生产一条数据
消费者获取到数据生产者pool-1-thread-9于【当前时间:2019-11-07 11:11:19 440】生产一条数据
消费者获取到数据生产者pool-1-thread-1于【当前时间:2019-11-07 11:11:19 440】生产一条数据
消费者获取到数据生产者pool-1-thread-7于【当前时间:2019-11-07 11:11:19 440】生产一条数据
消费者获取到数据生产者pool-1-thread-3于【当前时间:2019-11-07 11:11:19 441】生产一条数据
消费者获取到数据生产者pool-1-thread-2于【当前时间:2019-11-07 11:11:19 441】生产一条数据
消费者获取到数据生产者pool-1-thread-8于【当前时间:2019-11-07 11:11:19 442】生产一条数据
消费者获取到数据生产者pool-1-thread-4于【当前时间:2019-11-07 11:11:19 445】生产一条数据
消费者获取到数据生产者pool-1-thread-6于【当前时间:2019-11-07 11:11:19 450】生产一条数据
消费者获取到数据生产者pool-1-thread-1于【当前时间:2019-11-07 11:11:19 451】生产一条数据
消费者获取到数据生产者pool-1-thread-10于【当前时间:2019-11-07 11:11:19 451】生产一条数据
消费者获取到数据生产者pool-1-thread-7于【当前时间:2019-11-07 11:11:19 451】生产一条数据
消费者获取到数据生产者pool-1-thread-3于【当前时间:2019-11-07 11:11:19 451】生产一条数据
消费者获取到数据生产者pool-1-thread-9于【当前时间:2019-11-07 11:11:19 451】生产一条数据
消费者获取到数据生产者pool-1-thread-2于【当前时间:2019-11-07 11:11:19 451】生产一条数据
消费者获取到数据生产者pool-1-thread-5于【当前时间:2019-11-07 11:11:19 451】生产一条数据
消费者获取到数据生产者pool-1-thread-8于【当前时间:2019-11-07 11:11:19 453】生产一条数据
消费者获取到数据生产者pool-1-thread-4于【当前时间:2019-11-07 11:11:19 455】生产一条数据