(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 }