经典笔试题:线程通信(使用重入锁(ReentrantLock)和条件队列(Condition)实现线程间通信)

Posted gaopengpy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典笔试题:线程通信(使用重入锁(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

以上是关于经典笔试题:线程通信(使用重入锁(ReentrantLock)和条件队列(Condition)实现线程间通信)的主要内容,如果未能解决你的问题,请参考以下文章

经典笔试题:线程通信(使用CountDownLatch实现线程间通信)

经典笔试题:线程通信(使用wait,notify实现线程间通信)

多线程经典笔试题集锦

Java 多线程 重入锁

经典笔试题:两个线程交替打印奇偶数

ReentrantLock(重入锁)简单源码分析