“单例”模式-ThreadLocal线程单例

2019-11-24  本文已影响0人  wbpailxt

标题中单例之所以带着双引号,是因为并不能保证整个应用全局唯一,但是可以保证线程唯一。

package com.geely.design.pattern.creational.singleton;

/**
 * Created by geely
 */
public class ThreadLocalInstance {
    private static final ThreadLocal<ThreadLocalInstance> threadLocalInstanceThreadLocal
             = new ThreadLocal<ThreadLocalInstance>(){
        @Override
        protected ThreadLocalInstance initialValue() {
            return new ThreadLocalInstance();
        }
    };
    private ThreadLocalInstance(){

    }

    public static ThreadLocalInstance getInstance(){
        return threadLocalInstanceThreadLocal.get();
    }
}
package com.geely.design.pattern.creational.singleton;

/**
 * Created by geely
 */
public class T implements Runnable {
    @Override
    public void run() {
        ThreadLocalInstance instance = ThreadLocalInstance.getInstance();
        System.out.println(instance);
    }
}

测试类:

package com.geely.design.pattern.creational.singleton;

/**
 * Created by geely
 */
public class Test {
    public static void main(String[] args){
        System.out.println("main thread "+ThreadLocalInstance.getInstance());
        System.out.println("main thread "+ThreadLocalInstance.getInstance());
        System.out.println("main thread "+ThreadLocalInstance.getInstance());

        Thread thread0 = new Thread(new T());
        Thread thread1 = new Thread(new T());
        thread0.start();
        thread1.start();
    }
}

结果:


图片.png

两个线程(线程0和线程1)拿到的对象并不是同一个对象,但是同一线程能保证拿到的是同一个对象,即线程单例。
ThreadLocal是基于ThreadLocalMap来实现的,所以我们在调用get方法的时候,默认走的就是这个map,不用指定key,它维持了线程间的隔离。
ThreadLocal隔离了多个线程对数据的访问冲突。对多线程资源共享的问题,假如使用的是同步锁,那么就是以时间换空间的方式;那假如使用ThreadLocal,那就是用空间换时间的方式。

上一篇 下一篇

猜你喜欢

热点阅读