Thread synchronization tool use
- ReentrantLock
- Characteristic:
- Reentrant
- Interruptible: can interrupt the executing thread
- Time limited: set the time unit within which other business methods can be executed if no resources are obtained
- Fair lock: avoid starvation, but performance will be reduced
- Reentry lock implementation:
- cas status: judge whether the current lock is occupied
- Waiting queue: save all threads in waiting status in the queue
- park(): suspend the thread entering the queue. When the thread owning the lock releases the lock, it will call unpark() to start the first thread of the queue for resource access.
- Note: a reentry lock can also be called a recursive lock. When the outer method acquires the lock, the code segment or time method in the lock will acquire the lock by default. The thread that acquires the lock will enter any code that already has the lock.
- Add: the synchronized keyword is also a reentry lock, but it is indeed an unfair lock. After jdk1.5, the synchronized keyword is optimized, so there is not much difference between the two.
- Condition
- Summary
- Similar to Object.wait() and Object.notify()
- Need to be used with ReentrantLock
- Semaphore
- Summary:
- Shared lock
- Run multiple threads to enter the threshold. When only one thread is allowed to enter, it can be used as a common lock
- It can be used in some systems that cannot support too many requests. Use the shared lock to set the specific capacity. Threads exceeding the capacity will enter the waiting state
- ReadWriteLock
- Increase parallelism (read and write shackles)
- When there is no write function, the read thread is concurrent without waiting
- Read read non exclusive: no blocking between reads
- Read write mutex: read blocks write, and write blocks read
- Write write mutex: write block.
- CountDownLatch
- Countdown timer: as the name implies, a user-defined thread count is used to deduct the count during thread execution. When the count is deducted to 0, the countdown timer's waiting method in the main thread will be triggered for release.
- Give an example:
public class Test{
static final CountDownLatch end=new CountDownLatch(10);
static final MyThread td=new MyThread();
public static void main(String[] args) {
ExecutorService exec=Executors.newFixedThreadPool(10);
for (int i = 0; i < 10 ; i++) {
exec.execute(td);
}
exec.shutdown();
try {
end.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("launch");
}
}
class MyThread implements Runnable{
public void run(){
try {
Thread.sleep(new Random().nextInt(10)*100);
System.out.println(Thread.currentThread().getName()+"Checked");
} catch (InterruptedException e) {
e.printStackTrace();
}
Test.end.countDown();
}
}
Execution result:
pool-1-thread-7 checked
pool-1-thread-4 checked
pool-1-thread-1 checked
pool-1-thread-8 checked
pool-1-thread-3 checked
pool-1-thread-10 checked
pool-1-thread-6 checked
pool-1-thread-2 checked
pool-1-thread-5 checked
pool-1-thread-9 checked
launch
- CyclicBarrier
- Circular fence: similar to the countdown timer, but the cylicBarrier is a circular technology, which means that this counter can be used repeatedly. For example, if our counter is set to 10, the counter will return to zero after a batch of 10 threads are executed, and then the next batch of 10 threads will be prepared to intercept the incoming threads .
- Give an example:
public class CyclicBarrierTest
{
static final CyclicBarrier barrier=new CyclicBarrier(10,new MyBarrierAction());
static final MyThread1 td=new MyThread1();
public static void main(String[] args) {
ExecutorService exec= Executors.newFixedThreadPool(10);
for (int i = 0; i < 10 ; i++) {
exec.execute(td);
}
exec.shutdown();
}
}
class MyBarrierAction implements Runnable{
public void run() {
System.out.println("It's all over");
}
}
class MyThread1 implements Runnable{
public void run(){
try {
CyclicBarrierTest.barrier.await();
doWork();
CyclicBarrierTest.barrier.await();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
}
private static void doWork() {
try {
Thread.sleep(new Random().nextInt(10)*100);
System.out.println("thread"+Thread.currentThread().getName()+"Execution complete!");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Print results:
It's all over
Thread pool-1-thread-3 finished!
Finished executing thread pool-1-thread-9!
Finished executing thread pool-1-thread-6!
Finished executing thread pool-1-thread-8!
Finished executing thread pool-1-thread-2!
Thread pool-1-thread-4 finished!
Thread pool-1-thread-10 finished!
Finished executing thread pool-1-thread-7!
Thread pool-1-thread-5 finished!
Thread pool-1-thread-1 finished!
It's all over
Published 2 original articles, praised 0 and visited 35
Posted by jfarthing on Sun, 15 Mar 2020 05:09:12 -0700