ThreadLocal 的一点小理解

6 篇文章 0 订阅
3 篇文章 0 订阅

      网上关于Threadloal的文章很多,有时看多了我自己也搞不清这东西到底干嘛用的了,而且有些例子举得也是有问题的,下面我谈下自己的理解。

先摘抄一个别人的:

     ThreadLocal:允许我们创建只能被同一个线程读写的变量,例如Web应用中将变量从前端到后台,并且需要在这次请求的线程中始终可以随时获取到。

我的理解:

其实说得也比较好懂,我这只有一个变量,我也不想再创建了,但是偏偏有三个线程需要使用这个变量,如果单纯这么使用,那肯定是会出现线程安全问题;不能理解的话就再打个比喻,例如苍老师在拍片,此时有三个猛男都要跟苍老师啪啪啪,这肯定不行的嘛,要么你一个一个来还是可以的。

但是三个猛男偏偏都想要跟苍老师玩,而且都不想排队,这就麻烦了,此时。。。我们的导演ThreadLocal 来了,导演并不是空手而来,而是背着好几个以苍老师为模板的充气娃娃,然后对着那三个猛男说道,你们几个玩这个娃娃吧,让苍老师先休息一下。

三猛男此时都得到一个娃娃,然后就乐此不疲的去拍摄了。。。虽然没真人那么爽,但至少不用排队或者争着来了,也不会弄错了,只与自己的娃娃玩嘛,其他人的娃娃让他自己玩去!

下面我会用代码来表示一下:

1. 没使用ThreadLocal 的情况下:

import java.util.Random;

/**
 * Created by ThinkPad on 2017/3/10.
 */
public class NoThreadLocalTestCount {
    static  int count=1;
    public static void main(String[] args) {
        for(int i=0;i<3;i++){
            new Thread(new Runnable() {
                public void run() {
                    Random random = new Random();
                    count= random.nextInt(1000);
                    System.out.println(Thread.currentThread()+":"+count);
                    try {
                        Thread.sleep(1000);
                    }catch (Exception e){

                    }
                    Aclass.test();
                }
            }).start();
        }
    }
    static class Aclass{
        public static void test(){
            System.out.println("进入a模块:"+Thread.currentThread()+":"+count);
        }
    }
}

结果:

Thread[Thread-2,5,main]:398
Thread[Thread-1,5,main]:368
Thread[Thread-0,5,main]:348
进入a模块:Thread[Thread-2,5,main]:348
进入a模块:Thread[Thread-1,5,main]:348
进入a模块:Thread[Thread-0,5,main]:348

其实我希望的是输出结果是:

thread-1 368   

进入a模块:Thread[Thread-1,5,main]:368

但是结果都给我输出348,与预期结果不符合呀,因为多线程去操作时,变量count被改变了,另一线程拿到是别的线程改变后的结果。

为了杜绝这个问题,我们使用ThreadLocal来进行测试:

import java.util.Random;

/**
 * Created by ThinkPad on 2017/3/10.
 */
public class ThreadLocalTest {
    static  ThreadLocal <Integer> localCount=new ThreadLocal<Integer>();
    //线程独享该变量的副本,而并不影响其他线程获取该数据,即2个线程对该变量的操作互不影响,
    //适用于数据库连接管理,session管理等等,
    public static void main(String[] args) {
        for(int i=0;i<3;i++){
            new Thread(new Runnable() {
                public void run() {
                    Random random = new Random();
                    int count= random.nextInt(1000);
                    localCount.set(count);
                    System.out.println(Thread.currentThread()+":"+count);
                    try {
                        Thread.sleep(1000);
                    }catch (Exception e){

                    }
                    Aclass.test();
                }
            }).start();
        }
    }
    static class Aclass{
        public static void test(){
            System.out.println("进入a模块:"+Thread.currentThread()+":"+localCount.get());
        }
    }

结果:

Thread[Thread-0,5,main]:114
Thread[Thread-2,5,main]:75
Thread[Thread-1,5,main]:693
进入a模块:Thread[Thread-0,5,main]:114
进入a模块:Thread[Thread-1,5,main]:693
进入a模块:Thread[Thread-2,5,main]:75

哟...结果还是可以的嘛!对应的线程,哪怕中间有别的线程在操作,也不影响本线程的数据,我的依然是我的,你的还是你的,互不干扰挺好的。那个...听说strus2用这个保证接收的参数变量每个线程是隔离的,以前学习时也不太懂...现在想想确实也这么回事,要是不这样的话,写在action里的成员变量就乱咯,除非使用多例模式可避免。

嗯,今天先到此了,下次再见,拜拜!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值