ReentrantLock

reentrant

A single thread can repeatedly enter, but repeatedly exit

interruptible

 lockInterruptibly() 

Prevents threads from taking up a lot of time because they can’t complete operations late.

Can be timed

If a lock cannot be obtained by timeout, return false, and do not wait forever to form a deadlock

Fair lock

First come, first serve

public ReentrantLock(boolean fair)

 public static ReentrantLock fairLock = new ReentrantLock(true);

Example 1:

Standard usage:



Example 2:

The lock can be repeated twice in a row, but must also be unlocked twice, otherwise the thread freezes



Example 3:

interruptible

Lock1. lockInterruptably() in line 23; This method locks, indicating that the lock can be broken, and when broken, an exception is thrown



The last line of code, a daemon thread, checks for deadlocks as follows:





TryLock () can be used for a limited time:

The lock application fails.

The Condition Condition of a reentrant lock

An overview of the

Similar to object.wait () and object.notify () used in conjunction with ReentrantLock

The main interface

 void await() throws InterruptedException; 

void awaitUninterruptibly(); 

long awaitNanos(long nanosTimeout) throws InterruptedException; 

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

 boolean awaitUntil(Date deadline) throws InterruptedException; void signal(); 

void signalAll(); 

The API,

The await() method causes the current thread to wait while releasing the current lock, and when the signal() or signalAll() method is used in another thread, the line regains the lock and continues execution. Or when the thread is interrupted, it can jump out of the wait. This is similar to the object.wait () method.

The awaitUninterruptibly() method is essentially the same as the await() method, but it does not wait for the response to interrupt.

The singal() method is used to wake up a waiting thread. The relative singalAll() method wakes up all waiting threads. This is similar to the obejct.notify () method.

Example:



.awalt () The thread suspends and waits

.signal() wakes up the thread to continue execution and must regain the lock.

Semaphore (Semaphore, shared lock)

Overview Shared locks run multiple threads simultaneously with critical sections,

You can specify how many permissions threads are allowed to enter,

A thread can have one or more permissions, depending on the business logic

Exceeding the specified permissions will act as locks that do not allow threads to enter.

The main interface

// Get semaphore

 public void acquire()

// Get semaphore, interrupt is not supported

 public void acquireUninterruptibly()

// Try to get semaphore

 public boolean tryAcquire()

// Time limit attempt to obtain semaphore

 public boolean tryAcquire(long timeout, TimeUnit unit)

// Release semaphore

 public void release() 

A simple example:

A) acquire B) acquire C) acquire D) acquireRelease ()





Since the permission is 5, there are 20 threads, each with a delay of 2 seconds, so the result is a wave that completes every 2 seconds in four waves

ReadWriteLock (read-write lock)

An overview of the

ReadWriteLock is a read/write separation lock provided in JDK5 that allows multiple read operations. If there is no write operation, all read operations are concurrent without waiting.

All-thread locking can seriously affect performance, so you can use read-write split locking with separate features.

On visit

Read – Read not mutually exclusive: There is no blocking between reads.

Read – write mutex: Read blocks write, and write blocks read.

Write – write mutex: Write blocks.

The main interface

/ / the NEW object

private static ReentrantReadWriteLock readWriteLock=new ReentrantReadWriteLock(); 

// Get the read lock

private static Lock readLock = readWriteLock.readLock(); 

// Get the write lock

private static Lock writeLock = readWriteLock.writeLock(); 

// Lock to unlock

Lock () unlock ()

CountDownLatch

An overview of countdown timers A typical scenario is a rocket launch. Before the launch of a rocket, in order to ensure that everything is safe, often have to carry out the inspection of equipment and instruments. The engine can’t ignite until all the checks are done. This scenario is ideal for CountDownLatch. It can cause the firing thread to wait for all check threads to complete before executing

The main interface

// construct the number of threads that ⏲ counts

 static final CountDownLatch end = new CountDownLatch(10);

// Complete a thread

end.countDown();

// Start executing the main thread

end.await(); 

Schematic diagram



The main thread reaches a critical point and waits for other threads to finish their work before resuming execution.

Example:

CyclicBarrier

An overview of the

Cyclic fence Cyclic means Cyclic, which means the counter can be used over and over again. For example, suppose we set the counter to 10. So after the first batch of 10, 10 threads, the counter will go to zero, and then the next batch of 10 threads

The main interface

 public CyclicBarrier(int parties, Runnable barrierAction)

BarrierAction is the action that the system will perform when the counter has finished counting once

await() 

Schematic diagram

 

Code examples:



Note: The last three lines of code interrupt a thread’s operation, so an exception is thrown.

LockSupport (Thread blocking utility class)

An overview of the

Provides a thread blocking primitive

The main interface

// Stop the thread

LockSupport.park();

// The specified thread continues execution

LockSupport.unpark(t1);

Compared with the suspend ()

Less likely to cause thread freezing

Interrupt response

Able to respond to interrupts without throwing exceptions.

The result of the interrupt response is the return of the park() function, which gets the interrupt flag from Thread.interrupted()

The sample





A thread that is park () (suspended) and wants to continue, either unpark or is interrupted, and does not throw an interrupt exception.

The realization of the already

State of the CAS

The mechanism of locking is realized by CAS algorithm, which is the key to reentrant locking

Waiting queue

If the lock is not obtained, the queue is entered and all waiting threads are saved

park()

All waiting threads park (suspend). The first thread, UNLOCK, unpark (unsuspend), and unlock (unlock), and then unlock, and so on.

Concurrent container and typical source code analysis

A collection of packaging

HashMap

 Collections.synchronizedMap public static Map m=Collections.synchronizedMap(new HashMap()); 

This approach is only suitable for cases where the amount of concurrency is small because the implementation uses synchronous locking heavily.

Composition of HashMap:



List 

synchronizedList 

Again, use a synchronization lock

.Set 

synchronizedSet

Again, use a synchronization lock

ConcurrentHashMap 

High-performance HashMap

When the put operation is performed, the HashMap is divided into several smaller hashmaps (Segment<K,V>) and the operation is performed to avoid conflicts caused by large HashMap operations between threads.

BlockingQueue

Blocking queue

Thread safe, but not very good performance, in multi-threaded environment can play the role of sharing data

If the data is empty, the thread will wait until another thread writes to the data and wakes up the thread to read the data.

If the data is full, the thread can’t write until another thread has removed the data.

This is called a blocking queue and causes a thread to block

ConcurrentLinkedQueue

High performance linked list queue, same function, better performance, will not cause blocking