java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java多线程并发JUC包ReentrantLock显示锁

Java多线程并发JUC包ReentrantLock显示锁的用法

作者:二六八

这篇文章主要介绍了Java多线程并发JUC包ReentrantLock显示锁的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

Java多线程并发JUC包 ReentrantLock 显示锁

ReentrantLock支持以下功能:

公平锁与非公平锁:

1 lock 和 unlock 方法说明

该demo模拟电影院的售票情况,tickets总票数。开启了10个窗口售票,售完为止,程序代码如下:

public class ReentrantLockDemo01 implements Runnable {

    private Lock lock = new ReentrantLock();

    private int tickets = 50;

    @Override
    public void run() {
        while (true) {
            // 获取锁
            if (lock.tryLock()) {
                try {
                    if (tickets > 0) {
                        TimeUnit.MILLISECONDS.sleep(100);
                        System.out.println(Thread.currentThread().getName() + " " + tickets--);
                    } else {
                        break;
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock(); // 释放所
                }
            }

        }
    }

    public static void main(String[] args) {
        ReentrantLockDemo01 reentrantLockDemo = new ReentrantLockDemo01();
        for (int i = 0; i < 10; i++) {
            Thread thread = new Thread(reentrantLockDemo, "thread - " + i);
            thread.start();
        }
    }
}

输出如下 :

thread - 0 50
thread - 7 49
thread - 4 48
thread - 7 47
thread - 7 46
thread - 7 45
thread - 7 44
thread - 7 43
thread - 7 42
thread - 7 41
thread - 7 40
thread - 7 39
thread - 7 38
thread - 7 37
thread - 7 36
thread - 7 35
thread - 7 34
thread - 7 33
thread - 7 32
thread - 7 31
thread - 7 30
thread - 5 29
thread - 5 28
thread - 5 27
thread - 6 26
thread - 6 25
thread - 7 24
thread - 7 23
thread - 7 22
thread - 7 21
thread - 5 20
thread - 5 19
thread - 5 18
thread - 7 17
thread - 2 16
thread - 2 15
thread - 2 14
thread - 2 13
thread - 1 12
thread - 1 11
thread - 1 10
thread - 1 9
thread - 1 8
thread - 1 7
thread - 1 6
thread - 1 5
thread - 1 4
thread - 1 3
thread - 1 2
thread - 1 1

2 newCondition方法

Condition的作用是对锁进行更精确的控制。

Condition中的 await() 方法相当于Object的 wait() 方法,Condition中的 signal() 方法相当于Object的 notify() 方法,Condition中的 signalAll() 相当于Object的 notifyAll() 方法。

不同的是,Object中的 wait() , notify() , notifyAll() 方法是和”同步锁”(synchronized关键字)捆绑使用的;而Condition是需要与”互斥锁”/”共享锁”捆绑使用的。

/**
 * 生产者消费者
 */
public class ProducerConsumerTest {

    private Lock lock = new ReentrantLock();

    private Condition addCondition = lock.newCondition();

    private Condition removeCondition = lock.newCondition();

    private LinkedList<Integer> resources = new LinkedList<>();

    private int maxSize;

    public ProducerConsumerTest(int maxSize) {
        this.maxSize = maxSize;
    }


    public class Producer implements Runnable {

        private int proSize;

        private Producer(int proSize) {
            this.proSize = proSize;
        }

        @Override
        public void run() {
            lock.lock();
            try {
                for (int i = 1; i < proSize; i++) {
                    while (resources.size() >= maxSize) {
                        System.out.println("当前仓库已满,等待消费...");
                        try {
                            addCondition.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("已经生产产品数: " + i + "\t现仓储量总量:" + resources.size());
                    resources.add(i);
                    removeCondition.signal();
                }
            } finally {
                lock.unlock();
            }

        }
    }

    public class Consumer implements Runnable {

        @Override
        public void run() {
            String threadName = Thread.currentThread().getName();
            while (true) {
                lock.lock();
                try {
                    while (resources.size() <= 0) {
                        System.out.println(threadName + " 当前仓库没有产品,请稍等...");
                        try {
                            // 进入阻塞状态
                            removeCondition.await();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    // 消费数据
                    int size = resources.size();
                    for (int i = 0; i < size; i++) {
                        Integer remove = resources.remove();
                        System.out.println(threadName + " 当前消费产品编号为:" + remove);
                    }
                    // 唤醒生产者
                    addCondition.signal();
                } finally {
                    lock.unlock();
                }
            }

        }
    }

    public static void main(String[] args) throws InterruptedException {
        ProducerConsumerTest producerConsumerTest = new ProducerConsumerTest(10);
        Producer producer = producerConsumerTest.new Producer(100);
        Consumer consumer = producerConsumerTest.new Consumer();
        final Thread producerThread = new Thread(producer, "producer");
        final Thread consumerThread = new Thread(consumer, "consumer");
        producerThread.start();
        TimeUnit.SECONDS.sleep(2);
        consumerThread.start();
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文