Skip to content
DAILY QUOTE

“ ”

公平锁、非公平锁

公平锁: 非常公平, 不能够插队,必须先来后到!

非公平锁:非常不公平,可以插队 (默认都是非公平)

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

可重入锁

可重入锁(递归锁)

Synchronized版

java
package com.mystpet.suo;  
  
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() {  
        System.out.println(Thread.currentThread().getName() + " sms");  
        call(); // 这里也有锁  
    }  
  
    public synchronized void call() {  
        System.out.println(Thread.currentThread().getName() + " call");  
    }  
}

结果:

java
A sms
A call
B sms
B call

lock版:

java
package com.mystpet.suo;  
  
import java.util.concurrent.locks.Lock;  
import java.util.concurrent.locks.ReentrantLock;  
  
public class Demo02 {  
    public static void main(String[] args) {  
        Phone2 phone2=new Phone2();  
  
        new Thread(() -> {  
            phone2.sms();  
        },"A").start();  
  
        new Thread(() -> {  
            phone2.sms();  
        },"B").start();  
    }  
}  
class Phone2{  
    Lock lock=new ReentrantLock();  
    public void sms(){  
        lock.lock();   // 细节问题:lock.lock(); lock.unlock(); // lock 锁必须配对,否则就会死在里面  
        lock.lock();  
        try {  
            System.out.println(Thread.currentThread().getName() + " sms");  
            call(); // 这里也有锁  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        } finally {  
            lock.unlock();  
            lock.unlock();  
        }  
    }  
  
    public void call(){  
        lock.lock();  
        try {  
            System.out.println(Thread.currentThread().getName() + " call");  
        } catch (Exception e) {  
            throw new RuntimeException(e);  
        } finally {  
            lock.unlock();  
        }  
    }  
}

自旋锁

spinlock

我们来定义一个锁测试

java
package com.mystpet.suo;  
  
import java.util.concurrent.atomic.AtomicReference;  
  
/**  
 * 自旋锁  
 */  
  
public class SpinlockDemo {  
    AtomicReference<Thread> atomicReference=new AtomicReference<>();  
  
    // 加锁  
    public void myLock(){  
        Thread thread=Thread.currentThread();  
        System.out.println(Thread.currentThread().getName() + " myLock");  
  
        // 自旋锁  
        while(!atomicReference.compareAndSet(null,thread)){  
  
        }  
  
    }  
  
    // 解锁  
    public void myUnlock(){  
        Thread thread=Thread.currentThread();  
        System.out.println(Thread.currentThread().getName() + " myUnlock");  
        atomicReference.compareAndSet(thread,null);  
    }  
  
}

测试:

java
package com.mystpet.suo;  
  
import java.util.concurrent.TimeUnit;  
  
public class TestSpinLock {  
    public static void main(String[] args) throws InterruptedException {  
//        ReentrantLock reentrantLock = new ReentrantLock();  
//        reentrantLock.lock();  
//        reentrantLock.unlock();  
  
  
        //底层使用自旋锁  
        SpinlockDemo spinlockDemo = new SpinlockDemo();  
        SpinlockDemo lock = new SpinlockDemo();  
  
        new Thread(() -> {  
            lock.myLock();  
            try {  
                TimeUnit.SECONDS.sleep(3);  
            } catch (Exception e) {  
                throw new RuntimeException(e);  
            } finally {  
                lock.myUnlock();  
            }  
        }, "T1").start();  
  
        TimeUnit.SECONDS.sleep(1);  
  
        new Thread(() -> {  
            lock.myLock();  
            try {  
                TimeUnit.SECONDS.sleep(1);  
            } catch (Exception e) {  
                throw new RuntimeException(e);  
            } finally {  
                lock.myUnlock();  
            }  
        }, "T2").start();  
    }  
}

结果:

java
T1==> myLock
T2==> myLock
T1==> myUnlock
T2==> myUnlock

死锁

死锁是什么

死锁测试,怎么排除死锁:

java
package com.mystpet.suo;  
  
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() {  
        synchronized (lockA) {  
            System.out.println(Thread.currentThread().getName() + "lock:" + lockA + "=>get" + lockB);  
            try {  
                TimeUnit.SECONDS.sleep(2);  
            } catch (InterruptedException e) {  
                throw new RuntimeException(e);  
            }  
            synchronized (lockB) {  
                System.out.println(Thread.currentThread().getName() + "lock:" + lockB + "=>get" + lockA);  
            }  
        }  
    }  
}

解决问题

1、使用 jps -l 定位进程号

2、使用 jstack 进程号 找到死锁问题

面试,工作中! 排查问题:

1、日志 9人回答

2、堆栈 1人回答