Lock (Synchronized)
Before the emergence of Lock interface, the concurrent safe processing of multithreading in Java applications can only be solved based on the synchronized keyword. However, synchronized has some shortcomings in some scenarios, that is, it is not suitable for all concurrent scenarios. However, after Java 5, the emergence of Lock can solve the shortcomings of synchronized in some scenes. It is more flexible than synchronized.
public class AtomicDemo { private static int count=0; static Lock lock=new ReentrantLock(); public static void inc(){ lock.lock(); //Acquire lock (mutex) try { Thread.sleep(1); count++; } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock();//Release lock } } public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 1000; i++) { new Thread(()->AtomicDemo.inc()).start(); } Thread.sleep(4000); System.out.println("result:"+count); } }
Output result:
result:1000
Reentrantlock
ReentrantLock is a mutually exclusive lock.
Reentry lock: the thread that has obtained the lock can obtain the lock again without releasing the lock.
For example:
public class AtomicDemo { private static int count=0; //Reentry lock (how to implement it?) static Lock lock=new ReentrantLock(true); public static void inc(){ lock.lock(); //Get lock (mutex) ThreadA gets lock try { Thread.sleep(1); count++; decr(); } catch (InterruptedException e) { e.printStackTrace(); }finally { lock.unlock();//Release lock ThreadA release lock state=1-1=0 } } public static void decr(){ lock.lock(); //State = 2 / / threada preempts the lock again: it is not necessary to preempt the lock again, but only increase the number of reentries try{ count--; }finally { lock.unlock(); //state=1 } } public static void main(String[] args) throws InterruptedException { for (int i = 0; i < 1000; i++) { new Thread(()->AtomicDemo.inc()).start(); } Thread.sleep(4000); System.out.println("result:"+count); } }
If the lock cannot be re entered, A deadlock will occur when ThreadA calls the inc() method. Because A has obtained the lock for the first time, when calling decr(), if it cannot obtain the lock, it will block and deadlock.
Reentrantreadwritelock
It is suitable for reading more and writing less
1. Read and read are not mutually exclusive
2. Read and write are mutually exclusive
3. Write and write are mutually exclusive
ReentrantReadWriteLock maintains two locks, a read lock and a write lock.
public class Demo { static Map<String,Object> cacheMap=new HashMap<>(); static ReentrantReadWriteLock rwl=new ReentrantReadWriteLock(); static Lock read=rwl.readLock(); static Lock write=rwl.writeLock(); public static Object get(String key){ read.lock(); //Read lock ThreadA blocking try{ return cacheMap.get(key); }finally { read.unlock(); //Release read lock } } public static Object write(String key,Object value){ write.lock(); //Other Thread got write lock try{ return cacheMap.put(key,value); }finally { write.unlock(); } } }
StampedLock
Read more and write less Read and read are not mutually exclusive read and write are mutually exclusive write and write are mutually exclusive
Realization of thinking lock (design thinking)
{mutually exclusive}
1. Mutually exclusive property of lock - > shared resource () - > tag (0 has no lock, 1 has lock)
2. No thread preempting lock? - > Release CPU resources, [wait - > wake up]
3. How are waiting threads stored? - > The data structure is used to store some waiting threads. FIFO (waiting queue) 4, fair and unfair (whether to jump the queue), and synchronized is an unfair lock
5. Characteristics of reentry (identify whether it is the same person? ThreadID)
{technical proposal}
1. volatile state =0 (no lock), 1 means to hold the lock, and > 1 means to re-enter
2. wait/notify | condition failed to wake the specified thread.
You need to wake up the specified thread. [locksupport. Park(); - > unpark (thread)] a method provided in the unsafe class.
3. Bidirectional linked list
4. Logical level to achieve
5. Store the ID of the thread that currently obtains the lock in a certain place to judge whether the thread that preempts the lock next time is the same.