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
- Object A has two synchronization methods A, B.
- When we go into synchronous method A we get the lock on object A
- 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
- A thread A waits for the lock of object A
- The lock on object A has been acquired by thread B.
- 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
- Thread A is waiting for lock A, but lock A has been acquired by thread B
- Thread B is waiting for lock B, but lock B has been acquired by thread A
- 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