ShineYoung

导航

 

Java ReentrantLock

个人认为的好处主要在于用condition(await,signal)代替了synchronized的(wait,notify)

synchronized的(wait,notify)唤醒线程只能所有都唤醒或者唤醒随机一个

condition(await,signal)唤醒线程可以唤醒想要唤醒的线程类型

还有两个

指定公平锁还是非公平锁,默认非公平锁

提供lock().lockInterruptibly()实现中断等待锁的线程的机制(不太理解,日后补上)

看代码

package service;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
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;

class Product{
    public int id = 0; 
    public Product(int id) {
        this.id = id;
    }
}

class Producer extends Thread{
    private TestReentrantLock tsetReentrantLock; 
    private int id = 0;
    
    public Producer(TestReentrantLock tsetReentrantLock) {
        this.tsetReentrantLock = tsetReentrantLock;
    }
    
    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            Product product = new Product(id++);
            this.tsetReentrantLock.put(product);
        }
    }
}

class Consumer extends Thread{
    private TestReentrantLock testReentrantLock; 
    
    public Consumer(TestReentrantLock testReentrantLock) {
        this.testReentrantLock = testReentrantLock;
    }
    
    @Override
    public void run() {
        for (int i = 0; i < 50; i++) {
            this.testReentrantLock.get();
        }
    }
}


class TestReentrantLock{
    private final int MAX = 10;
    private int count = 0;

    LinkedList<Product> list = new LinkedList<>();
    
    private Lock lock = new ReentrantLock();
    private Condition producer = lock.newCondition();
    private Condition consumer = lock.newCondition();
    
    public int getCount() {
        return count;
    }
    
    public void put(Product product) {
        lock.lock();
        while(list.size() >= MAX) {
            System.out.println(Thread.currentThread().getName() + "队列已满,生产者等待中");
            try {
                producer.await();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        consumer.signalAll();
        count++;
        System.out.println(Thread.currentThread().getName() + "生产" + product.id + "ing" + "队列已使用" + count + "/10");
        list.add(product);
        lock.unlock();
    }
    
    public void get() {
        lock.lock();
        while(list.size() == 0) {
            System.out.println(Thread.currentThread().getName() + "队列已空,消费者等待中");
            try {
                consumer.await();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        producer.signalAll(); 
        count--;
        Product product = list.removeFirst();
        System.out.println(Thread.currentThread().getName() + "消费" + product.id + "ing" + "队列已使用" + count + "/10");
        lock.unlock();
    }
}


public class ReentrantLockTest {
    public static void main(String[] args) {
        TestReentrantLock testReentrantLock = new TestReentrantLock();
        Producer producer = new Producer(testReentrantLock); 
        Consumer consumer = new Consumer(testReentrantLock);
        producer.start();
        consumer.start();
    }
}

我将condition分为生产者和消费者,condition精准唤醒效率更高,不会出现synchronized一起唤醒生产者和消费者导致的阻塞

posted on 2019-03-04 20:55  ShineYoung  阅读(147)  评论(0编辑  收藏  举报