Multithreading are two ways to communicate with you? (Reentrant lock ReentrantLock and Object)

(A) Java threads collaboration The two most common ways:

       (1) the use of wait Object (), notify () and notifyAll () method and synchronized

       (2) Condition, ReentrantLock 

(Ii) Object class wait (), notify () and notifyAll () method

 1 /**
 2  * Wakes up a single thread that is waiting on this object's
 3  * monitor. If any threads are waiting on this object, one of them
 4  * is chosen to be awakened. The choice is arbitrary and occurs at
 5  * the discretion of the implementation. A thread waits on an object's
 6  * monitor by calling one of the wait methods
 7  */
 8 public final native void notify();
 9  
10 /**
11  * Wakes up all threads that are waiting on this object's monitor. A
12  * thread waits on an object's monitor by calling one of the
13  * wait methods.
14  */
15 public final native void notifyAll();
16  
17 /**
18  * Causes the current thread to wait until either another thread invokes the
19  * {@link java.lang.Object#notify()} method or the
20  * {@link java.lang.Object#notifyAll()} method for this object, or a
21  * specified amount of time has elapsed.
22  * <p>
23  * The current thread must own this object's monitor.
24  */
25 public final native void wait(long timeout) throws InterruptedException;

  From the text of the three methods described can know the following information:

  1) wait (), notify () and notifyAll () method is a local method, and a method for the final and can not be rewritten.

  2) call to wait an object () method allows the current thread to block and monitor the current thread must own this object (ie lock)

  3) call an object's notify () method can be a wake-up is waiting for this object's monitor thread, if there are multiple threads waiting on this object's monitor, you can only wake up one thread;

  4) call notifyAll () method can awaken all are waiting for the object monitor thread;

(C) Lock the interface, ReentrantLock, Condition Description

3.1 Key Concepts: reentrancy

   This can be a problem reentrancy Description: When a thread holding a lock, within it can once again (several times) to apply the lock. If a thread lock has been obtained, it can also be repeatedly applied inside the lock success. Then we say that the lock is reentrant lock. Described by the following pseudo-code:

. 1  void methodA () {
 2      Lock.lock (); // acquiring the lock 
. 3      methodB ();
 . 4      lock.unlock () // release lock 
. 5  }
 . 6  
. 7  void methodB () {
 . 8      Lock.lock (); // acquiring the lock
 9      // other business 
10      lock.unlock (); // release lock 
11 }

Reentrant lock can be understood as a lock identifier. The identification function includes a counter. The initial value of 0 logo representing the current lock is not held by any thread. When each thread obtains a reentrant lock, the lock counter is incremented by one. Each time a thread is released and the lock counter decrements. Provided that: the current thread has acquired the lock, the scene appeared again to acquire the lock inside thread

Implementation Notes 3.2 ReentrantLock
ticket sales demo the analog cinema, tickets total number of votes. Opened 10 ticket window, while supplies last

 1 public class ReentrantLockDemo01 implements Runnable {
 2 
 3     private Lock lock = new ReentrantLock();
 4 
 5     private int tickets = 200;
 6 
 7     @Override
 8     public void run() {
 9         while (true) {
10             lock.lock(); // 获取锁
11             try {
12                 if (tickets > 0) {
13                     TimeUnit.MILLISECONDS.sleep(100);
14                     System.out.println(Thread.currentThread().getName() + " " + tickets--);
15                 } else {
16                     break;
17                 }
18             } catch (InterruptedException e) {
19                 e.printStackTrace();
20             } finally {
21                 lock.unlock(); // 释放所
22             }
23         }
24     }
25 
26     public static void main(String[] args) {
27         ReentrantLockDemo01 reentrantLockDemo = new ReentrantLockDemo01();
28         for (int i = 0; i < 10; i++) {
29             Thread thread = new Thread(reentrantLockDemo, "thread" + i);
30             thread.start();
31         }
32     }
33 }

3.3 lockInterruptibly in () Method Description

As can be seen from the Lock source: lockInterruptibly () throws an exception interrupt

1 void lockInterruptibly() throws InterruptedException;

3.4 tryLock (), tryLock (long time, TimeUnit unit) Method Description

tryLock () method returns immediately obtain the current situation.

tryLock (long time, TimeUnit unit) wait for a certain period of time, the situation returns to get

 1 public class ReentrantLockDemo03 implements Runnable {
 2 
 3     private ReentrantLock lock = new ReentrantLock();
 4 
 5     @Override
 6     public void run() {
 7         try {
 8             if (lock.tryLock(2, TimeUnit.SECONDS)) {
 9                 System.out.println(Thread.currentThread().getName() + " 获取当前lock锁");
10                 TimeUnit.SECONDS.sleep(4);
11             } else {
12                 System.out.println(Thread.currentThread().getName()+ " 获取锁失败");
13             }
14         } catch (InterruptedException e) {
15             e.printStackTrace();
16         } finally {
17             if (lock.isHeldByCurrentThread()) {
18                 lock.unlock();
19             }
20         }
21     }
22 
23 
24     public static void main(String[] args) {
25         ReentrantLockDemo03 reentrantLockDemo = new ReentrantLockDemo03();
26         Thread thread01 = new Thread(reentrantLockDemo, "thread01");
27         Thread thread02 = new Thread(reentrantLockDemo, "thread02");
28         thread01.start();
29         thread02.start();
30     }

 

3.5 newCondition () Method Description

Currently just newCondition () use will be described, there is no in-depth analysis of Condition () to realize source.
Action lock is Condition more precise control. Await Condition in () method is equivalent to the Object wait () method, signal Condition in () method of the Object corresponding to notify () method, Condition of signalAll () corresponds notifyAll Object () method. The difference is, Object of the wait (), notify (), notifyAll () method and the "Genlock" (the synchronized keyword) bundled; and Condition requires the "mutex" / "shared lock" bundling in use.

 3.6 Condition

Condition is only appeared in java 1.5, which is used to replace the traditional Object's wait (), notify () to achieve cooperation between the threads, compared to the use of Object wait (), notify (), using Condition1 the await () , signal () in this way to achieve cooperation between threads more secure and efficient. Therefore, it is rather generally recommended Condition, blocking queue in a blog post that tells you to, in fact blocking queue is used to simulate Condition collaboration between threads.

  • Condition is the interface, the basic approach is the await () and signal () method;
  • Lock Condition depends on the interface, generate a substantially Condition codes are lock.newCondition () 
  •  Condition of calling await () and signal () method, must be within lock protection, that must only be used between lock.lock () and lock.unlock

  Conditon in the await () corresponding to the wait of Object ();

  Condition of the signal () corresponding to the Notify Object ();

  Condition in signalAll () corresponding to the notifyAll Object ().

(Iv) multi-thread communication in two ways

. 1  Package cn.csrc.base.cpu;
 2  Import java.util.concurrent.locks.Condition;
 . 3  Import java.util.concurrent.locks.ReentrantLock;
 . 4  / ** 
. 5  * 
 . 6  * Function: two threads communicate ways (1) Object (2) ReentrantLock
 7  * @author : ZSQ
 8  * the Create DATE: 2019 Nian 7 2 December, afternoon 4:23:41
 9  * modify modification times people describe
 10  * Copyright 
 11   * / 
12  public  class {OddEvenPrinter
 13 is  
14      // first method as the lock object 
15      Private   Final Object obj=new Object(); 
16     
17     //第二种方法
18     private final ReentrantLock lock=new ReentrantLock();
19     private final Condition condition=lock.newCondition();
20     
21     private  int limit;
22     private volatile int count;
23     
24     public OddEvenPrinter(int limit,int count){
25         this.limit=limit;
26         this.count=count;
27     }
28     
29     //Object锁
30     public void myPrint1(){
31         synchronized (obj) {
32             while(count<limit){
33                 try {
34                     System.out.println(String.format("线程[%s]打印数字:%d",Thread.currentThread().getName(),++count));
35                     obj.notifyAll();
36                     obj.wait();
37                 } catch (Exception e) {
38                     e.printStackTrace();
39                 }
40              }
 41 is          }
 42 is      }
 43 is      
44 is      // of ReentrantLock reentrant lock 
45      public  void myPrint2 () {
 46 is          // entered on the lock 
47          Lock.lock ();
 48          the try {
 49              the while (COUNT < limit) {
 50                  the System. out.println (String.format (. "thread [% s] digital Print:% D", Thread.currentThread () getName (), ++ COUNT));
 51 is                  condition.signalAll (); // wake-locked the thread 
52              }
 53          } the catch(Exception E) {
 54 is              e.printStackTrace ();
 55          } the finally {
 56 is              // finally releases the lock 
57 is              lock.unlock ();
 58          }
 59      }
 60      
61 is      public  static  void main (String [] args) throws InterruptedException {
 62 is           OddEvenPrinter = Print new new OddEvenPrinter (10, 0 );
 63 is           System.err.println ( "first method ----------- ----------- Object" );
 64           the Thread = Thread1 new new Thread(print::myPrint1, "thread-A");
65          Thread thread2 = new Thread(print::myPrint1, "thread-B");
66          thread1.start();
67          thread2.start();
68          Thread.sleep(1000);
69          
70          System.err.println("-----------第二种方法 lock-----------");
71          Thread thread3 = new Thread(print::myPrint2, "thread-C");
72          Thread thread4 = new Thread(print::myPrint2, "thread-D");
73          thread3.start();
74          thread4.start();
75          Thread.sleep(1000);
76     }
77 
78 }

 

Guess you like

Origin www.cnblogs.com/zhaosq/p/11121440.html