The understanding of various locks
1, fair lock, unfair lock
Fair lock: very fair, can not jump the queue, must come first!
Unfair lock: Very unfair, can cut in line (default is unfair)
public ReentrantLock(a) {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
Copy the code
2. Reentrant lock
Reentrant lock (recursive lock)
Synchronized
package com.chao.lock;
//Synchronized
public class Demo01 {
public static void main(String[] args) {
Phone phone = new Phone();
new Thread(()->{
phone.sms();
},"A").start();
new Thread(()->{
phone.sms();
},"B").start(); }}class Phone{
public synchronized void sms(a){
System.out.println(Thread.currentThread().getName() + "sms");
call(); // There is a lock here too
}
public synchronized void call(a){
System.out.println(Thread.currentThread().getName() + "call"); }}Copy the code
The Lock version
package com.chao.lock;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Demo02 {
public static void main(String[] args) {
Phone2 phone = new Phone2();
new Thread(()->{
phone.sms();
},"A").start();
new Thread(()->{
phone.sms();
},"B").start(); }}class Phone2{
Lock lock = new ReentrantLock();
public void sms(a){
lock.lock();// Details; lock.lock(); lock.unlock(); //lock The lock must be paired, or it will die inside
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "sms");
call(); // There is a lock here too
} catch (Exception e) {
e.printStackTrace();
} finally{ lock.unlock(); lock.unlock(); }}public void call(a){
lock.lock();
try {
System.out.println(Thread.currentThread().getName() + "call");
}catch (Exception e) {
e.printStackTrace();
} finally{ lock.unlock(); }}}Copy the code
3. Spin locks
spinlock
Let’s customize a lock test
package com.chao.lock;
import java.util.concurrent.atomic.AtomicReference;
/** ** spin lock */
public class SpinlockDemo {
//int 0
//Thread null
AtomicReference<Thread> atomicReference = new AtomicReference<>();
/ / lock
public void myLock(a){
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName()+"==>mylock");
/ / the spin lock
while(! atomicReference.compareAndSet(null,thread)){
}
}
/ / unlock
public void myUnLock(a){
Thread thread = Thread.currentThread();
System.out.println(Thread.currentThread().getName()+"==>myUnlock");
atomicReference.compareAndSet(thread,null); }}Copy the code
test
package com.chao.lock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
public class TestSpinLock {
public static void main(String[] args) throws InterruptedException {
// ReentrantLock reentrantLock = new ReentrantLock();
// reentrantLock.lock();
// reentrantLock.unlock();
// The underlying spinner CAS
SpinlockDemo lock = new SpinlockDemo();
new Thread(()->{
lock.myLock();
try {
TimeUnit.SECONDS.sleep(5);
} catch (Exception e) {
e.printStackTrace();
} finally{ lock.myUnLock(); }},"T1").start();
TimeUnit.SECONDS.sleep(1);
new Thread(()->{
lock.myLock();
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {
e.printStackTrace();
} finally{ lock.myUnLock(); }},"T2").start(); }}Copy the code
4, a deadlock
What is a deadlock
Deadlock test, how to eliminate deadlock:
package com.chao.lock;
import java.util.concurrent.TimeUnit;
public class DeadLockDemo {
public static void main(String[] args) {
String lockA = "lockA";
String lockB = "lockB";
new Thread(new MyThread(lockA,lockB),"T1").start();
new Thread(new MyThread(lockB,lockA),"T2").start(); }}class MyThread implements Runnable{
private String lockA;
private String lockB;
public MyThread(String lockA, String lockB) {
this.lockA = lockA;
this.lockB = lockB;
}
@Override
public void run(a) {
synchronized (lockA){
System.out.println(Thread.currentThread().getName()+"lock:"+lockA+"=>get"+lockB);
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (lockB){
System.out.println(Thread.currentThread().getName()+"lock:"+lockB+"=>get"+lockA); }}}}Copy the code
To solve the problem
jdk bin
1. Use ‘JPS -l’ to locate the process number
2. Use the jStack process number to find the deadlock problem