ReentrantLock implemented using printed alternately blocking queue

I. Introduction

  1.ReentrantLock is reentrant lock means one thread can enter any code block that thread has a lock synchronization with, and to achieve the Lock interface through Condition fine control multithreading Wake.

  2.Lock Interface

    // get the lock, get less lock will not give up, can not be interrupted, even if the current thread is interrupted, the thread blocks until the lock to get, relatively rogue practices. 
    void Lock (); 
    
   / ** 
   * Gets lock, interruptible, before acquiring the lock if the current thread is interrupt, 
   * After acquiring the lock will throw InterruptedException, and stops the current thread; 
   * priority response interrupt 
   * / 
    void lockInterruptibly () throws InterruptedException; 

    // return immediately results; attempts to obtain a lock if the lock is obtained immediately return ture, failed to return immediately false 
    boolean tryLock (); 

    // try to get a lock, you can set the timeout, timeout returns false, ie the date is not waiting 
    boolean tryLock ( Long Time, TimeUnit Unit) throws InterruptedException; 

    // release the lock 
    void UNLOCK (); 
    
    // returns Condition current thread, can be called multiple times
    Condition newCondition();

  3.Condition Interface

public  interface for condition Condition {
     / ** 
    * for condition Condition thread into the blocked state, call signal () or signalAll () wakes up again, 
    * enable interrupts If the lock is held by a thread interrupted while blocked, it will throw an exception; 
    * The important thing is: In the current lock holds a thread, after the external call will await (), ReentrantLock allows other threads to snatch the current lock lock 
    * Note: to make the thread wait by creating a Condition object, you must first perform lock.lock way to get lock 
    * / 
    void the await () throws InterruptedException; 

    // for condition condition thread into the blocked state, call signal () or signalAll () wakes up again, not allowed to interrupt, if the thread holding the lock interrupted while blocked, continue to wait wake 
    void awaitUninterruptibly (); 

    // setting the blocking time, the timeout continues timeout nanoseconds, the other with the await (); return time is greater than zero, indicating a wake-up, as the waiting time and the waiting time can be a desired value less than zero indicates that the timeout 
    Long awaitNanos ( Long nanosTimeout) throws InterruptedException;

    // Similar awaitNanos (long nanosTimeout); Return Value: wakes up true, the timeout to false 
    Boolean the await ( Long Time, TimeUnit Unit) throws InterruptedException; 

   // similar to the await (Long Time, TimeUnit Unit) 
    Boolean awaitUntil (a Date DEADLINE) throws InterruptedException; 

   // wake specified thread 
    void Signal (); 
    
    // wake up all threads 
    void signalAll (); 
}

Second, the realization blocking queue

  1. Implement

public class BlockQueue {
    //队列容器
    private List<Integer> container = new ArrayList<>();
    private Lock lock = new ReentrantLock();
    //队列为空
    private Condition isNull = lock.newCondition();
    //队列已满
    private Condition isFull = lock.newCondition();
    private volatile int size;
    private volatile int capacity;

    BlockQueue(int cap){
        this.capacity = cap;
    }

     {public  void the Add ( int Data) {
         the try { 
            Lock.lock (); 
            the while (size> = Capacity) { 
                System.out.println ( "queue is full, release the lock, waiting for consumer spending" );
                 the try { 
                    isFull.await (); 
                } the catch (InterruptedException E) { 
                    e.printStackTrace (); 
                } 
            }
             ++ size; 
            Container.add (Data); 
            isNull.signal (); 
        } the finally 
        }
            lock.unlock (); 
    } 

    public  int Take () {
         the try { 
            Lock.lock (); 
            the while (0 == size) { 
                System.out.println ( "empty queue blocking, release the lock, waiting for producers to produce data" );
                 the try { 
                    isNull.await (); 
                } the catch (InterruptedException E) { 
                    e.printStackTrace (); 
                } 
            }
             - size;
             int RES = container.get (0 ); 
            Container.remove ( 0 ); 
            isFull.signal (); 
            return RES;
        }finally {
            lock.unlock();
        }
    }
}

  2. Test and operating results

public class BlockQueueTest {
    public static void main(String[] args) {
        BlockQueue queue = new BlockQueue(5);
        Thread thread1 = new Thread(()->{
           for(int i=0;i<100;i++){
               queue.add(i);
               System.out.println("生产:" + i);
               try {
                   Thread.sleep(300);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           }
        });
        Thread thread2 = new Thread(()->{
            for(;;){
                System.out.println("消费者开始工作,消费:" + queue.take());
                try {
                    Thread.sleep(600);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });

        thread1.start();
        thread2.start();
    }
}

  Test Results:

 

 

 

 Third, alternating print

  1. Implement

public class AlternateTask {
    public static void main(String[] args) {
        ReentrantLock lock = new ReentrantLock();
        Condition condition1 = lock.newCondition();
        Condition condition2 = lock.newCondition();
        Thread thread1 = new Thread(()->{
            try {
                lock.lock();
                for (int i=1;i<100;i+=2){
                   System.out.println("-----thread1-----" + i );
                   condition1.await();
                   condition2.signal();
                   Thread.sleep(500);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        });
        Thread thread2 = new Thread(()->{
           try {
               lock.lock();
               for(int i=2;i<101;i+=2){
                   System.out.println("-----thread2-----" + i);
                   condition1.signal();
                   condition2.await();
                   Thread.sleep(500);
               }
           } catch (InterruptedException e){
               e.getStackTrace();
           } finally {
               lock.unlock();
           }

        });
        thread1.start();
        thread2.start();
    }
}

  2 Test and operating results

 

 

 

 IV Conclusion

  This article is made of two classic demo ReentrantLock simple implementation, please correct me if flawed, learn together and progress together.

 

Guess you like

Origin www.cnblogs.com/ghoster/p/12503082.html