多线程下单例模式的实现_ThreadLocal_ReentrantLock

package threadStudy;

public class MultiThreadSingleInstance {

    // volatile  防止指令重排
    private static volatile MultiThreadSingleInstance instance;

    private MultiThreadSingleInstance() {

    }

    public static MultiThreadSingleInstance getInstance() {
        if (instance != null)
            return instance;
        else {
            //给字节码文件加锁
            synchronized (MultiThreadSingleInstance.class) {
                instance = new MultiThreadSingleInstance();
                return instance;
            }
            
        }
    }
    
    public static void main(String[] args) {
        new Thread(()->{
            System.out.println(MultiThreadSingleInstance.getInstance());
        }) .start();
        System.out.println(MultiThreadSingleInstance.getInstance());
    }
}

返回的地址一样  说明只创建了一个对象


 线程局部变量:https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ThreadLocal.html


ReentrantLock的原理就是内部设置一个计数器,每次加锁的时候的如果计数器为0则成功加锁,如果不为0且持有锁的线程不是当前线程,则请求加锁的线程等待,否则,获得锁,且计数器值加一。

package threadStudy;

import java.util.concurrent.locks.ReentrantLock;

public class ReentrantLockTest {

    private final ReentrantLock lock = new ReentrantLock();
    
    void a() {
        lock.lock();
        //返回当前线程持有的锁的数量
        System.out.println(lock.getHoldCount());
        b();
        System.out.println(lock.getHoldCount());
        lock.unlock();
        System.out.println(lock.getHoldCount());
    }
    
    void b() {
        lock.lock();
        //返回当前线程持有的锁的数量
        System.out.println(lock.getHoldCount());
        lock.unlock();
    }
    
    
    public static void main(String[] args) {
        new ReentrantLockTest().a();
    }

}

 

posted @ 2019-06-13 10:08  Practical  阅读(441)  评论(0编辑  收藏  举报