java concurrency - learning ReentrantLock

Learn ReentrantLock

What is a Dian ReentrantLock

  ReentrantLock is java and an implementation contract locks, it is re-entry lock, ie, after acquiring the lock, the lock itself is available again, does not in itself cause a deadlock, it could be considered a substitute for the keyword sychronized, but it there are more than sychronized feature-rich, such as providing Condition waiting to provide interrupt functions. 

Two Dian ReentrantLock function

  ReentrantLock realized the Lock interface, so it has the following features

  1. Obtain lock

void lock();

  2. Get the lock, waiting process can be interrupted

void lockInterruptibly() throws InterruptedException;

  3. Try to obtain a lock if the lock is not acquired, return immediately

boolean tryLock();

  4. The attempt to acquire the lock, and waits for the specified time, after the specified time is exceeded, or the interrupt return immediately

boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

  5. Release lock

void unlock();

  6. New Condition

Condition newCondition();

 

Wed and use examples

 

  Use ReentrantLock thread-safe blocking queue

public class BlockingQueue {
    
    private int[] datas;
    private int count;
    private int firstIndex;
    private int endIndex;
    
    private ReentrantLock lock=new ReentrantLock();
    
    // 未空的条件, 等待take
    private final Condition notEmpty = lock.newCondition();
    // 未满的条件, 等待put
    private final Condition notFull = lock.newCondition();
    
    
    public BlockingQueue(int capacity) {
        this.datas = new new  int [Capacity];
         the this .count = 0 ; 
    } 
    
    public  void PUT ( int Data) throws InterruptedException {
         Final of ReentrantLock = Lock the this .lock; 
        lock.lockInterruptibly (); // Get lock 
        the try {
             the while (COUNT == DATAS. length) { // this loop determines the need to add 
                notFull.await ();   // wait condition under 
            } 
            the enqueue (Data); 
        } the finally { 
            lock.unlock (); 
        } 
    }
    
    public  int Take () throws InterruptedException {
         Final of ReentrantLock = Lock the this .lock; 
        lock.lockInterruptibly (); // Get lock 
        the try {
             the while (COUNT == 0) {   // this loop determines the need to add 
                notEmpty.await (); // wait is not empty 
            }
             int Data = dequeue ();
             return Data; 
        } the finally { 
            lock.unlock (); 
        } 
    } 
    
    Private  void the enqueue (int Data) { 
        DATAS [endIndex] = Data; 
        
        
        endIndex ++ ;
         IF (endIndex == datas.length) { 
            endIndex = 0 ; 
        } 
        
        COUNT ++ ; 
        notEmpty.signal ();   // for condition Condition signal, the internal queue the first thread in the queue moved Lock 
    } 
    
    Private  int dequeue () {
         int Data = DATAS [firstIndex]; 
     
        firstIndex ++ ;
         IF (firstIndex == datas.length) { 
            firstIndex = 0  ;
        }
        
        count--;
        notFull.signal();
        return data;
    }
    
}

 

  Scenario testing classes:

public class ReentrantTests {

    public static void main(String[] args) throws InterruptedException {
        // 
        BlockingQueue blockingQueue=new BlockingQueue(20);
        
        Thread producer=new Thread(new ProducerRunnable(blockingQueue, 1));
        Thread consumer1=new Thread(new ConsumerRunnable("消费者1", blockingQueue, 2));
        Thread consumer2=new Thread(new ConsumerRunnable("消费者2", blockingQueue, 3));
        
        
        producer.start();
        consumer1.start();
        consumer2.start();
        
//        producer.join();
        consumer1.join();
        consumer2.join();
    }
    
    
    
}
class ProducerRunnable implements  Runnable{

    private BlockingQueue bq;
    private int interval;
    
    public ProducerRunnable(BlockingQueue bq, int interval) {
        this.bq = bq;
        this.interval=interval;
    }

    @Override public void run() {
        int mix=10000;
        int i=0;
        try {
            while(i<mix){
                this.bq.put(i);
                i++;
                System.out.println("生产者停顿"+interval*100+"ms...");
                Thread.sleep(interval * 100);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}


class ConsumerRunnable implements  Runnable{

    private BlockingQueue bq;
    private int interval;
    private String name;

    public ConsumerRunnable(String name,BlockingQueue bq, int interval) {
        this.name = name;
        this.bq = bq;
        this.interval=interval;
    }

    @Override public void run() {
        int mix=10000;
        int i=0;
        try {
            while(i<mix){
                int data=this.bq.take();
                System.out.println(this.name+"获取数据"+data);
                System.out.println(this.name+"停顿"+interval*100+"ms...");
                Thread.sleep(interval * 100);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

 

  Complete source code: ReentraLock  



Guess you like

Origin www.cnblogs.com/timfruit/p/10962870.html