文档章节

【12】Java中的ThreadLocal

秋雨霏霏
 秋雨霏霏
发布于 2017/08/29 11:19
字数 731
阅读 45
收藏 1

Java中的ThreadLocal类,可以让你创建一个只能在同一个线程中读/写的变量。 即使两个线程同时获取了ThreadLocal的引用,但是ThreadLocal引用的变量对于两个线程来说仍然对彼此来说是不可见的。

创建

创建一个ThreadLocal很简单,比如:

private ThreadLocal myThreadLocal = new ThreadLocal();

直接new一个ThreadLocal对象即可。 对每个线程来说,只需要一次创建。 虽然是一个成员变量,其他线程都可能访问到这个代码,但是,每个线程都只能看到自己的ThreadLoacl实例。 即使不同的线程可以再ThreadLocal中设置不同的值(对象),但是,对于线程来说,只能看到属于自己的那个值。

访问

创建ThreadLocal之后,就可以在其中设置(存放)一个值(对象)。如:

myThreadLocal.set("A thread local value");

如果想要使用存放在ThreadLocal中的值(对象),可以这样:

String threadLocalValue = (String) myThreadLocal.get();

使用泛型

可以创建一个泛型ThreadLocal,这样就可以不需要对返回对象的类型进行强转了。

private ThreadLocal<String> myThreadLocal = new ThreadLocal<String>();

这样定义,那ThreadLocal实例中,就只能存放String类型了。当然好处就是,获取对象时就不需要类型处理了:

myThreadLocal.set("Hello ThreadLocal");

String threadLocalValue = myThreadLocal.get();

初始化

由于ThreadLocal中存放的对象,只对存放操作的线程可见。 这样,就不会有线程可以通过ThreadLocalset方法,设定一个初始值

如果需要设定一个初始值,可以继承ThreadLocal,在子类中覆盖initialValue()方法。比如这样:

private ThreadLocal myThreadLocal = new ThreadLocal<String>() {
    @Override protected String initialValue() {
        return "This is the initial value";
    }
};  

这样,所有的线程都可以看到同样的初始值了。

完整的例子

public class ThreadLocalExample {


    public static class MyRunnable implements Runnable {

        private ThreadLocal<Integer> threadLocal =
               new ThreadLocal<Integer>();

        @Override
        public void run() {
            threadLocal.set( (int) (Math.random() * 100D) );
    
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
    
            System.out.println(threadLocal.get());
        }
    }


    public static void main(String[] args) {
        MyRunnable sharedRunnableInstance = new MyRunnable();

        Thread thread1 = new Thread(sharedRunnableInstance);
        Thread thread2 = new Thread(sharedRunnableInstance);

        thread1.start();
        thread2.start();

        thread1.join(); //wait for thread 1 to terminate
        thread2.join(); //wait for thread 2 to terminate
    }

}

上例中,同一个MyRunnable实例,在两个线程中运行。 两个线程都会执行MyRunnable实例的run方法,因此,不同线程会在ThreadLocal中存放不同的数值。 如果不是ThreadLocal而是其他类型,而且没有使用同步机制的话,那第二个线程就会覆盖set方法的数值。

但是,使用ThreadLocal就不需要担心这些问题了,两个线程看不到对方的数值,他们会存放自己的数值,而不会彼此覆盖。

InheritableThreadLocal

Java还为ThreadLocal提供了一个子类:InheritableThreadLocal。 区别在于:

  • ThreadLocal对于每一个线程都是不同的可见范围
  • InheritableThreadLocal可以为当前线程创建的子线程授权访问自己的InheritableThreadLocal数据

© 著作权归作者所有

秋雨霏霏
粉丝 148
博文 94
码字总数 168411
作品 0
杭州
CTO(技术副总裁)
私信 提问
访问不了http://localhost:8080/ecommerce和https://localhost:8443/webtools?

1.ofbiz版本是:ofbiz12 2.根据这篇博文(http://blog.csdn.net/xiaoliouc/article/details/10223095?reload#html),前面都没有问题,但是在最后一步: 1)执行ant load-demo,成功创建了数...

对岸
2014/11/12
3.2K
2
centos groovy环境建立

#wget -S http://dist.groovy.codehaus.org/distributions/groovy-binary-1.6.1.zip Unzip it: #unzip groovy-binary-1.6.1.zip set the environment: vi /etc/profile export GROOVYHOME=/e......

hjswust
2013/08/13
0
1
[20171215]oracle执行java程序.txt

[20171215]oracle执行java程序.txt --//我以前提到假如oracle调用执行java程序会在/dev/shm下建立一堆JOXSHM_EXT开头的文件(实际上在内存中) --//如果异常关闭数据库这些文件就会留在内存中....

lfreeali
2017/12/15
0
0
java servic wrapper jvm启动五遍后就停止

STATUS | wrapper | 2013/04/03 12:01:35 | Launching a JVM... INFO | jvm 1 | 2013/04/03 12:01:36 | there are all ok ERROR | wrapper | 2013/04/03 12:01:36 | JVM exited while loadin......

这个世界不真实
2013/04/03
1K
1
我该用 Java 12 还是坚持 Java 11?

本文经授权转自开源中国 距离 Java 11 的正式发布已过去一个多月,而 Java 12 也正在赶来的路上。根据此前开源中国发起的一项关于开发者使用的 Java 版本的调查(https://www.oschina.net/q...

CSDN资讯
2018/11/05
0
0

没有更多内容

加载失败,请刷新页面

加载更多

GMTC2019|闲鱼-基于Flutter的架构演进与创新

作者:闲鱼技术-宗心 2012年应届毕业加入阿里巴巴,主导了闲鱼基于Flutter的新混合架构,同时推进了Flutter在闲鱼各业务线的落地。未来将持续关注终端技术的演变及趋势 Flutter的优势与挑战 ...

阿里云云栖社区
20分钟前
2
0
迪蒙人工智能共享停车吸引国际关注

  近来,华为创始人任正非多次提及人工智能。即便在华为生死攸关的关键时刻,任正非依旧不忘强调教育的重要性,“如果不重视教育,实际上我们会重返贫穷的,因为这个社会,最终是要走向人工智能的...

琴殇的
22分钟前
0
0
iOS开发之EventKitUI框架的应用

iOS开发之EventKitUI框架的应用 前面博客,有介绍EventKit这个框架的使用,使用EventKit可以与系统的日历和提醒应用进行交互,读写用户的日程事件。EventKitUI,顾名思义,其实基于EventKit框...

珲少
30分钟前
0
0
从MySQL源码看其网络IO模型

从MySQL源码看其网络IO模型 前言 MySQL是当今最流行的开源数据库,阅读其源码是一件大有裨益的事情(虽然其代码感觉比较凌乱)。而笔者阅读一个Server源码的习惯就是先从其网络IO模型看起。于是...

无毁的湖光-Al
30分钟前
0
0
WebService学习笔记

什么是Web Services? Web Services 是应用程序组件 Web Services 使用开放协议进行通信 Web Services 是独立的(self-contained)并可自我描述 Web Services 可通过使用UDDI来发现 Web Serv...

榴莲黑芝麻糊
47分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部