Java线程同步可重入锁ReentrantLock与Condition

import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

public class Main {
    private Queue mQueue;

    public static void main(String[] args) {
        Main main = new Main();
        try {
            main.test();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void test() {
        mQueue = new LinkedList<>();

        ReentrantLock lock = new ReentrantLock();
        Condition producerLock = lock.newCondition();
        Condition consumerLock = lock.newCondition();

        /**
         * 生产者,消费者,数据同步。
         * 只有生产者先把数据生产出来,消费者才可以消费。
         * 先生产,再消费。
         * 生产者线程和消费者线程保存执行序列:生产->消费。
         */
        consumer(lock, producerLock, consumerLock);
        producer(lock, producerLock, consumerLock);
    }

    /**
     * 消费者。
     *
     * @param lock
     * @param producerLock
     * @param consumerLock
     */
    private void consumer(ReentrantLock lock, Condition producerLock, Condition consumerLock) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    lock.lock();


                    /**
                     * 如果队列为空,则表明数据为空,消费者等待,等待生产者生产。
                     */
                    if (mQueue.size() == 0) {
                        try {
                            consumerLock.await();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                    int data1 = mQueue.poll();
                    int data2 = mQueue.poll();
                    System.out.println("后消费:" + data1 + "," + data2);
                    System.out.println("-----");
                    mQueue.clear();

                    /**
                     * 给生产者发送信号,已经把数据消费,生产者可以开始生产。
                     */
                    producerLock.signal();


                    lock.unlock();
                }
            }
        }).start();
    }

    /**
     * 生产者。
     *
     * @param lock
     * @param producerLock
     * @param consumerLock
     */
    private void producer(ReentrantLock lock, Condition producerLock, Condition consumerLock) {
        //生产数据。
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 15; i++) {
                    lock.lock();


                    /**
                     * 如果队列不为空,则表明队列满。生产者等待,等待消费者把数据消费掉。
                     */
                    if (mQueue.size() != 0) {
                        try {
                            producerLock.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }

                    mQueue.offer(i);
                    mQueue.offer(i + 1);
                    System.out.println("先生产:" + i + "," + (i + 1));

                    /**
                     * 生产者已经把数据生产完成,发送信号给消费者,可以消费了。
                     */
                    consumerLock.signal();


                    lock.unlock();
                }
            }
        }).start();
    }
}

 

输出:

先生产:0,1
后消费:0,1
-----
先生产:1,2
后消费:1,2
-----
先生产:2,3
后消费:2,3
-----
先生产:3,4
后消费:3,4
-----
先生产:4,5
后消费:4,5
-----
先生产:5,6
后消费:5,6
-----
先生产:6,7
后消费:6,7
-----
先生产:7,8
后消费:7,8
-----
先生产:8,9
后消费:8,9
-----
先生产:9,10
后消费:9,10
-----
先生产:10,11
后消费:10,11
-----
先生产:11,12
后消费:11,12
-----
先生产:12,13
后消费:12,13
-----
先生产:13,14
后消费:13,14
-----
先生产:14,15
后消费:14,15
-----

 

你可能感兴趣的:(Java,线程,多线程,Java多线程,Java,多线程,线程)