ThreadLocal变量
来源:互联网 发布:js在线格式化工具 编辑:程序博客网 时间:2024/06/05 15:00
在做ThreadLocal时遇到了一件特别郁闷的事。因为ThreadLocal是线程独享的,但是我在做程序开发时却遇到一个问题,就是ThreadLocal里总是有另外一个线程插入的数据。最后终于发现,原来启动的两个线程都是main线程,不知道为什么。。。。。。。。。
clean项目,重启MyEclipse后,问题解决了。。。。。。。。。。
紧接着又一件郁闷事来了。在使用线程池时,如果某一个线路中运行含有ThreadLocal变量时,当将这个线程释放回线程池时,再次取出后,这时的ThreadLocal还会保存上次运行时的结果,而不会重置线程。所以我的程序出现有时正确、有时错误的状态。。。。。。。
来看一个实例:
- public class SequenceNumber {
- // overwrite the ThreadLocal method initialValue() to set a initial value
- private static ThreadLocal<Integer> seqNum = new ThreadLocal<Integer>() {
- public Integer initialValue() {
- return 0;
- }
- };
- // get next number
- public int getNextNum() {
- seqNum.set(seqNum.get() + 1);
- return seqNum.get();
- }
- public static void main(String[] args) {
- SequenceNumber sn = new SequenceNumber();
- // 3 threads use the same number variable and increase it
- TestClient t1 = new TestClient(sn);
- TestClient t2 = new TestClient(sn);
- TestClient t3 = new TestClient(sn);
- t1.start();
- t2.start();
- t3.start();
- }
- private static class TestClient extends Thread {
- private SequenceNumber sn;
- public TestClient(SequenceNumber sn) {
- this.sn = sn;
- }
- public void run() {
- for (int i = 0; i < 3; i++) {
- // every thread print 3 number
- System.out.println("thread[" + Thread.currentThread().getName()
- + "] sn[" + sn.getNextNum() + "]");
- }
- }
- }
- }
运行的结果如下:
- thread[Thread-2] sn[1]
- thread[Thread-2] sn[2]
- thread[Thread-2] sn[3]
- thread[Thread-1] sn[1]
- thread[Thread-1] sn[2]
- thread[Thread-1] sn[3]
- thread[Thread-0] sn[1]
- thread[Thread-0] sn[2]
- thread[Thread-0] sn[3]
如果两个线程要共享同一个变量,除了这个变量为静态变量外,还可以传递引用达到共享目的,如下:
- public class TestThreadLocal {
- public static void main(String[] args) throws InterruptedException {
- // 两个线程共享字符串常量
- String ss = "xx";
- // 两个线程共享引用类型变量
- List l = new ArrayList();
- l.add("xxx");
- // 两个线程共享引用变量
- ThreadLocal<List<String>> list = new ThreadLocal<List<String>>();
- list.set(new ArrayList<String>());
- new TestClient(ss,l,list).run();
- Thread.sleep(1000);
- System.out.println(ss + l +list.get());
- }
- private static class TestClient extends Thread {
- private String sn;
- private List p;
- private ThreadLocal<List<String>> li;
- public TestClient(String sn,List p,ThreadLocal<List<String>> li) {
- this.sn = sn;
- this.p = p;
- this.li = li;
- }
- public void run() {
- sn = "bbbbbbb";
- for (int i = 0; i < 3; i++) {
- p.add("xxxx-" + i);
- li.get().add("th+"+i);
- System.out.println(sn + p);
- }
- }
- }
- }
最后运行的结果如下:
- bbbbbbb[xxx, xxxx-0]
- bbbbbbb[xxx, xxxx-0, xxxx-1]
- bbbbbbb[xxx, xxxx-0, xxxx-1, xxxx-2]
- xx[xxx, xxxx-0, xxxx-1, xxxx-2][th+0, th+1, th+2]
再来看一个例子,如下:
- public class AbstractA {
- public void init(){
- List<String> l = new ArrayList<String>();
- l.add("张三");
- l.add("李四");
- if(DataStore.getList().get()==null){
- DataStore.getList().set(l);
- }
- }
- }
- public class ClassicB extends AbstractA{
- public void b() {
- init();
- DataStore.getList().get().add("a");
- DataStore.getList().get().add("b");
- // 打印结果
- System.out.println(DataStore.getList().get());
- }
- }
- public class Main {
- static ClassicB b = new ClassicB();
- public static void main(String[] args) {
- b.b();
- b.b();
- new SynchronizedTask().start();
- new SynchronizedTask().start();
- }
- private static class SynchronizedTask extends Thread {
- public void run() {
- b.b();
- }
- }
- }
[张三, 李四, a, b]
[张三, 李四, a, b, a, b]
[张三, 李四, a, b]
[张三, 李四, a, b]
可以看到ThreadLocal是每个线程独享的。
0 0
- ThreadLocal变量
- ThreadLocal变量
- ThreadLocal变量
- ThreadLocal变量
- ThreadLocal 与 static 变量
- ThreadLocal---线程本地变量
- 如何使用ThreadLocal变量
- 线程局部变量ThreadLocal
- ThreadLocal 线程局部变量
- ThreadLocal 线程变量
- ThreadLocal---线程本地变量
- 线程局部变量ThreadLocal
- ThreadLocal线程局部变量
- 线程局部变量ThreadLocal
- 线程局部变量ThreadLocal
- 线程变量 ThreadLocal
- lk中的threadlocal 变量
- ThreadLocal,线程本地变量
- 主机字节序
- Apache Kafka消息传递可靠性分析
- (转载)测试用例设计综合策略
- SD卡中FAT32文件格式快速入门(图文详细介绍)
- C++开发中的栈、堆和内存分配
- ThreadLocal变量
- VMWare虚拟机提供的桥接、nat和主机模式的区别
- 阴影处理
- 模板方法(Template Pattern)
- 剧情插件Cutscene Creator uSequencer 1.3.7.1使用说明一
- Redis 学习笔记(一)安装与配置
- ConcurrentHashMap原理分析
- zookeeper学习笔记(三) —— 锁机制
- mysql常用命令大全