一、使用并发性好的Map集合
以Map集合为例进行说明,将线程的名称作为键,线程的本地变量作为值,存储在Map集合中。然后在需要的地方,获取当前线程的名称,根据当前线程名称获取值。如下:
public class Test {
private static Map<String, Integer> map = Collections.synchronizedMap(new HashMap<>());
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
new Thread(() -> {
int nextDouble = new Random().nextInt();
map.put(Thread.currentThread().getName(), nextDouble);
System.out.println(Thread.currentThread().getName() + " " + nextDouble);
Demo1 demo1 = new Demo1();
Demo2 demo2 = new Demo2();
demo1.getData1();
demo2.getData2();
}).start();
}
}
public static class Demo1 {
public void getData1() {
//System.out.println(Thread.currentThread().getName() + " " + "getData1:" + nextDouble);
System.out.println(Thread.currentThread().getName() + " " + "getData1:" + map.get(Thread.currentThread().getName()));
}
}
public static class Demo2 {
public void getData2() {
//System.out.println(Thread.currentThread().getName() + " " + "getData2:" + nextDouble);
System.out.println(Thread.currentThread().getName() + " " + "getData2:" + map.get(Thread.currentThread().getName()));
}
}
}
打印效果如下,能够精准的获取不出错:
二、使用LocalThread
ThreadLocal只能存放一个数据,如果有多种类型的数据需要创建多个ThreadLocal。ThreadLocal可以实现创建不同线程的对象,而不是去使用synchronized 。关于ThreadLocal的源码解读请参考另一篇文章:https://blog.csdn.net/yoonerloop/article/details/78405863。下面请看案例。
public class Test2 {
private static ThreadLocal<Integer> local = new ThreadLocal<>();
public static void main(String[] args) {
for (int i = 0; i < 2; i++) {
new Thread(() -> {
int nextDouble = new Random().nextInt();
local.set(nextDouble);
System.out.println(Thread.currentThread().getName() + " " + nextDouble);
Demo1 demo1 = new Demo1();
Demo2 demo2 = new Demo2();
demo1.getData1();
demo2.getData2();
}).start();
}
}
public static class Demo1 {
public void getData1() {
//System.out.println(Thread.currentThread().getName() + " " + "getData1:" + nextDouble);
System.out.println(Thread.currentThread().getName() + " " + "getData1:" +local.get());
}
}
public static class Demo2 {
public void getData2() {
//System.out.println(Thread.currentThread().getName() + " " + "getData2:" + nextDouble);
System.out.println(Thread.currentThread().getName() + " " + "getData2:" + local.get());
}
}
}
这样可以更加快捷方便的获取到数据,性能比第一种方法更高,打印结果如下:
总结完毕!