14、各种锁的理解

2020-11-25  本文已影响0人  i小雨

1、公平锁、非公平锁

//默认为非公平锁
public ReentrantLock() {
        sync = new NonfairSync();
    }

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

2、可重入锁

可重入锁又名递归锁,是指在同一个线程在外层方法获取锁的时候,再进入该线程的内层方法会自动获取锁(前提锁对象得是同一个对象或者class),不会因为之前已经获取过还没释放而阻塞。Java中ReentrantLock和synchronized都是可重入锁,可重入锁的一个优点是可一定程度避免死锁。

图片.png
Synchronized:
//测试可重入锁:synchronized
public class reentrant {

    public static void main(String[] args) {

        Phone phone = new Phone();

        new Thread(()->{
            phone.email();
        },"A").start();

        new Thread(()->{
            phone.email();
        },"B").start();

        new Thread(()->{
            phone.call();
        },"C").start();
    }
}

class Phone{

    public synchronized void email(){
        System.out.println(Thread.currentThread().getName()+"->email");
        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        call(); //该方法也加了锁
    }

    public synchronized void call(){
        System.out.println(Thread.currentThread().getName()+"->call");

    }

}
******************************结果:**********************************
A->email
A->call
C->call
B->email
B->call

ReentrantLock:

//测试可重入锁:ReentrantLock
public class TestReentrantLock {
    public static void main(String[] args) {

        Phone2 phone = new Phone2();

        new Thread(()->{
            phone.email();
        },"A").start();

        new Thread(()->{
            phone.email();
        },"B").start();

        new Thread(()->{
            phone.call();
        },"C").start();
    }
}

class Phone2{

    Lock lock = new ReentrantLock();

    public synchronized void email(){
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+"->email");

            TimeUnit.SECONDS.sleep(2);

            call(); //该方法也加了锁
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public synchronized void call(){
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName()+"->call");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
}
***************************结果:*****************************
A->email
A->call
C->call
B->email
B->call
上一篇 下一篇

猜你喜欢

热点阅读