经典笔试题:线程通信(使用重入锁(ReentrantLock)和条件队列(Condition)实现线程间通信)
经典笔试题:
1、自定义容器,提供新增元素(add)和获取元素数量(size)方法。
2、启动两个线程。线程1向容器中新增10个数据。线程2监听容器元素数量,当容器元素数量为5时,线程2输出信息并终止。
package com.gaopeng.programming.test2; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * 练习:使用重入锁(ReentrantLock)和条件队列(Condition) * 自定义容器,提供新增元素(add)和获取元素数量(size)方法。 * 启动两个线程。线程1向容器中新增10个数据。线程2监听容器元素数量,当容器元素数量为5时,线程2输出信息并终止。 */ public class Test04 { public static void main(String[] args) { final Test03Container myContainer = new Test03Container(); final Lock lock = new ReentrantLock(); final Condition producer = lock.newCondition(); final Condition consumer = lock.newCondition(); new Thread(new Runnable() { @Override public void run() { lock.lock(); try { System.out.println(Thread.currentThread().getName() + "获得锁"); if (myContainer.size() != 5) { // 进入等待队列,释放锁标记 System.out.println(Thread.currentThread().getName() + "释放锁"); consumer.await(); } System.out.println("size = 5"); producer.signalAll(); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } }, "CONSUMER").start(); new Thread(new Runnable() { @Override public void run() { lock.lock(); try { System.out.println(Thread.currentThread().getName() + "获得锁"); for (int i = 1; i <= 10; i++) { System.out.println("add Object to Container " + i); myContainer.add(new Object()); if (myContainer.size() == 5) { consumer.signalAll(); // 进入等待队列,释放锁标记 System.out.println(Thread.currentThread().getName() + "释放锁"); producer.await(); } TimeUnit.SECONDS.sleep(1); } } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } }, "PRODUCER").start(); } } class Test04Container { List<Object> container = new ArrayList<>(); public void add(Object o) { this.container.add(o); } public int size() { return this.container.size(); } }
运行结果如下:
CONSUMER获得锁
CONSUMER释放锁
PRODUCER获得锁
add Object to Container 1
add Object to Container 2
add Object to Container 3
add Object to Container 4
add Object to Container 5
PRODUCER释放锁
size = 5
add Object to Container 6
add Object to Container 7
add Object to Container 8
add Object to Container 9
add Object to Container 10