标题中单例之所以带着双引号,是因为并不能保证整个应用全局唯一,但是可以保证线程唯一。
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,那就是用空间换时间的方式。
网友评论