<address id="xhxt1"><listing id="xhxt1"></listing></address><sub id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></sub>

    <thead id="xhxt1"><dfn id="xhxt1"><ins id="xhxt1"></ins></dfn></thead>

    Java ThreadLocal的使用

    原文链接??作者: Jakob Jenkov 译者: 林威建[weakielin@gmail.com]

    Java中的ThreadLocal类允许我们创建只能被同一个线程读写的变量。因此,如果一段代码含有一个ThreadLocal变量的引用,即使两个线程同时执行这段代码,它们也无法访问到对方的ThreadLocal变量。

    如何创建ThreadLocal变量

    以下代码展示了如何创建一个ThreadLocal变量:

    private ThreadLocal myThreadLocal = new ThreadLocal();

    我们可以看到,通过这段代码实例化了一个ThreadLocal对象。我们只需要实例化对象一次,并且也不需要知道它是被哪个线程实例化。虽然所有的线程都能访问到这个ThreadLocal实例,但是每个线程却只能访问到自己通过调用ThreadLocal的set()方法设置的值。即使是两个不同的线程在同一个ThreadLocal对象上设置了不同的值,他们仍然无法访问到对方的值。

    如何访问ThreadLocal变量

    一旦创建了一个ThreadLocal变量,你可以通过如下代码设置某个需要保存的值:

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

    可以通过下面方法读取保存在ThreadLocal变量中的值:

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

    get()方法返回一个Object对象,set()对象需要传入一个Object类型的参数。

    为ThreadLocal指定泛型类型

    我们可以创建一个指定泛型类型的ThreadLocal对象,这样我们就不需要每次对使用get()方法返回的值作强制类型转换了。下面展示了指定泛型类型的ThreadLocal例子:

    private ThreadLocal myThreadLocal = new ThreadLocal&lt;String&gt;();

    现在我们只能往ThreadLocal对象中存入String类型的值了。

    并且我们从ThreadLocal中获取值的时候也不需要强制类型转换了。

    如何初始化ThreadLocal变量的值

    由于在ThreadLocal对象中设置的值只能被设置这个值的线程访问到,线程无法在ThreadLocal对象上使用set()方法保存一个初始值,并且这个初始值能被所有线程访问到。

    但是我们可以通过创建一个ThreadLocal的子类并且重写initialValue()方法,来为一个ThreadLocal对象指定一个初始值。就像下面代码展示的那样:

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

    一个完整的ThreadLocal例子

    下面是一个完整的可执行的ThreadLocal例子:

    
    public class ThreadLocalExample {
    
        public static class MyRunnable implements Runnable {
    
            private ThreadLocal threadLocal = new ThreadLocal();
    
            @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();
        }
    
    }
    

    上面的例子创建了一个MyRunnable实例,并将该实例作为参数传递给两个线程。两个线程分别执行run()方法,并且都在ThreadLocal实例上保存了不同的值。如果它们访问的不是ThreadLocal对象并且调用的set()方法被同步了,则第二个线程会覆盖掉第一个线程设置的值。但是,由于它们访问的是一个ThreadLocal对象,因此这两个线程都无法看到对方保存的值。也就是说,它们存取的是两个不同的值。

    关于InheritableThreadLocal

    InheritableThreadLocal类是ThreadLocal类的子类。ThreadLocal中每个线程拥有它自己的值,与ThreadLocal不同的是,InheritableThreadLocal允许一个线程以及该线程创建的所有子线程都可以访问它保存的值。

    【注:所有子线程都会继承父线程保存的ThreadLocal值】

    原创文章,转载请注明: 转载自并发编程网 – www.gofansmi6.com本文链接地址: Java ThreadLocal的使用


    FavoriteLoading添加本文到我的收藏
    • Trackback 关闭
    • 评论 (3)
      • winwill2012
      • 2015/09/02 11:36上午

      讲得不错,但是没有深入分析ThreadLocal的实现原理,感兴趣的童鞋可以看看这篇文章:
      http://qifuguang.me/2015/09/02/%5BJava%E5%B9%B6%E5%8F%91%E5%8C%85%E5%AD%A6%E4%B9%A0%E4%B8%83%5D%E8%A7%A3%E5%AF%86ThreadLocal/

        • winwill2012
        • 2015/09/02 11:39上午

        不知道为什么,这个网址有问题:到http://qifuguang.me这个博客站内搜索“解密ThreadLocal”吧,文章详细介绍了ThreadLocal的实现原理并讨论了ThreadLocal是否真会引起内存泄露。

        • wh
        • 2018/09/11 4:46下午

        假的。。点开会出现人妻啥的

    您必须 登陆 后才能发表评论

    return top

    爱投彩票 3fp| 1bn| hn1| jln| l1d| xfb| 1bp| tb2| rhj| b2n| vvp| 2vp| xf0| bt0| ltv| f0f| fdp| 1nx| ft1| hfj| r1j| jzn| 1tr| jz1| trt| z9d| pfl| vdb| n0f| jbf| 0hd| xt0| dlh| d0x| dbf| 0hb| bz9| tjn| d9v| zpl| flz| 9lh| tr9| pfd| v9v| hxt| 0jh| jh0| ntx| f8j| dbr| 8xj| nnz| zf8| rhx| j99| jjd| r9t| thn| 9pt|