Fair lock

First come, first served, no cutting in line

 public ReentrantLock(boolean fair) {
        sync = fair ? new FairSync() : new NonfairSync();
    }
Copy the code

Not fair lock

Allow queue-jumping, generally default non-fair lock, higher efficiency

public ReentrantLock(a) {
        sync = new NonfairSync();
    }
Copy the code

Reentrant lock

This allows the same thread to acquire the same lock more than once

Implementation: synchronized, ReentrantLock

  1. Object A has two synchronization methods A, B.
  2. When we go into synchronous method A we get the lock on object A
  3. From a we call B and we need to get the lock on object A again. This is allowed
public class LockTest {
    public static void main(String[] args) {
        new Thread(()->{
            a();
        }).start();
    }
    public static synchronized void a(a){
        System.out.println("a");
        b();
    }
    public static synchronized void b(a){
        System.out.println("b"); }}Copy the code

spinlocks

  1. A thread A waits for the lock of object A
  2. The lock on object A has been acquired by thread B.
  3. Thread A enters A while loop to wait instead of sleep
public static void main(String[] args) throws InterruptedException {
        myLock myLock=new myLock();
        Thread 0 will rest for 2 seconds after acquiring the lock
        new Thread(()->{
            myLock.mylock();
            try{
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                myLock.myunlock();
            }

        }).start();
        TimeUnit.SECONDS.sleep(1);
        Thread 1 spins and waits for the lock to be released while thread 0 is resting to acquire the lock
        new Thread(()->{
            try{
                myLock.mylock();
            }finally{ myLock.myunlock(); } }).start(); }}Copy the code
class myLock{
    private AtomicReference<Thread> atomicReference=new AtomicReference<>();
    public void mylock(a){
        Thread thread=Thread.currentThread();
        System.out.println(thread.getName()+"->>mylock");
        // Wait for a loop
        while(! atomicReference.compareAndSet(null,thread)){};
    }
    public void myunlock(a){
        Thread thread=Thread.currentThread();
        System.out.println(thread.getName()+"->>myunlock");
        / / release
        atomicReference.compareAndSet(thread,null); }}Copy the code

A deadlock

  1. Thread A is waiting for lock A, but lock A has been acquired by thread B
  2. Thread B is waiting for lock B, but lock B has been acquired by thread A
  3. Waiting for each other forever

The necessary conditions for a deadlock to occur:

  • Mutually exclusive: A process requires exclusive control over allocated resources, that is, a resource is occupied by only one process during a period of time.
  • Request and hold conditions: When a process is blocked by requesting resources, it holds on to acquired resources.
  • Non-preemption: Resources cannot be preempted. That is, resources can be released only after a process completes a task
  • Circular wait: When a deadlock occurs, there must be a process, a circular chain of resources.

Deadlock screening

JPS -l Checks the process jstack for deadlocks