Thread-SpecificStorage
Thread-SpecificStorage Pattern是只有一个入口,但内部会对每个线程提供特有存储空间的Pattern。
比如说有一个保管箱间,里面有许多用户的保管箱,当多个用户进入房间使用保管箱时,进到的是同一个房间,但一定是只能打开自己的保管箱,只能对自己的保管箱提取或放置物品。
ThreadLocal
n public void set()
ThreadLocal类的set方法,可以将参数所指定的实例,存放到调用set方法的线程(现在的线程)所对应的存储空间。这里所存放的实例,可以使用get方法取得。注意set方法并没有用来传入表示线程的参数。在set方法里,会检查当前线程(也就是Thread.currentThread()的值),自动以这个值作为键值存放实例。
n public Object get()
ThreadLocal类的get方法,可以取得调用get方法的线程所对应的实例(现在线程对应的实例)。之前set的实例,就是现在get的返回值。如果从来没有set过,就会返回null。与set方法一样,get方法也没有表示线程的参数。因为程序会在get里自己去检查现在的线程。也就是说自己本身就是键值。
程序示例
多个线程同时打印序号。每个线程的序号从1开始,各自按递增1的顺序打印序号。
public final class SequenceNumber {
privatestatic final ThreadLocal<Integer> threadLocal = newThreadLocal<Integer>() {
protectedInteger initialValue() {
return1;
};
};
publicstatic int getSequenceNumber() {
intnumber = threadLocal.get();
threadLocal.set(number+ 1);
returnnumber;
}
}
public class PrintThread extends Thread {
publicPrintThread(String threadName) {
super(threadName);
}
@Override
publicvoid run() {
while(true) {
System.out.println(Thread.currentThread().getName()+ " : "
+SequenceNumber.getSequenceNumber());
try{
Thread.sleep(500);
}catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
publicstatic void main(String[] args) {
newPrintThread("AAA").start();
newPrintThread("BBB").start();
newPrintThread("CCC").start();
}
}
从运行结果可以看出,各个线程各自按照自己的序号顺序打印。