• 技术文章 >Java >java教程

    Java本地线程(ThreadLocal)

    黄舟黄舟2017-02-28 10:52:49原创607
    这个在Java中的ThreadLocal类可以保证使你创建的变量只能被相同的线程读和写。因此,甚至如果两个线程正在执行相同的代码,并且这个代码有一个对于ThreadLocal变量的引用,然后这两个线程就不能看到彼此的ThreadLocal变量。

    创建一个ThreadLocal

    这里有一个代码现实如何创建一个ThreadLocal:

    private ThreadLocal myThreadLocal = new ThreadLocal();


    正如你看到的,你实例化一个新的ThreadLocal对象。这个每个线程只需要做一次。甚至如果不同的线程执行访问一个ThreadLocal的相同的代码,每一个线程将只会看到它自己的ThreadLocal实例。甚至如果两个线程设置不同的值在这相同的ThreadLocal对象上,它们都不会看到彼此的值。

    访问一个ThreadLocal

    一旦一个ThreadLocal被创建了,你就可以像下面这样设置一个值去存储:

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

    你可以像下面这样去读这个值:

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

    这个get方法返回一个对象,并且这个set方法传递一个对象作为参数。

    泛型化的ThreadLocal

    你可以创建一个泛型化的ThreadLocal,以至于你不用在调用get方法的时候进行强制转化了。这里有一个例子:

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

    现在你只能存储存储字符串类型在ThreadLocal实例中。另外的,你不需要强制转化这个值了:

    myThreadLocal.set("Hello ThreadLocal");
    
    String threadLocalValue = myThreadLocal.get();


    初始化ThreadLocal值

    因为设置一个ThreadLocal对象的值只是对于设置这个值的线程可见的,所以没有线程可以使用set方法设置ThreadLocal的值对所有的线程可见。

    代替的,你可以通过子类ThreadLocal特指一个初始化的值对于一个ThreadLocal对象,以及覆盖initialValue方法。像下面这样:


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


    现在所有的线程可以看到相同的初始化值,在调用set方法之前。

    完整的ThreadLocal实例

    这里有一个完整运行的ThreadLocal实例

    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实例,它被传递给了两个不同的线程。这两个线程都执行了run方法,并且在ThreadLocal实例上设置了不同的值。如果对于这个set方法的调用访问是同步的,并且它还没有使用ThreadLocal对象,第二个线程将会覆盖第一个线程设置的值。

    然而,因为它是一个ThreadLocal对象,不能看到彼此的值。因此,他们设置和得到不同的值。

    InheritableThreadLocal

    这个InheritableThreadLocal类是ThreadLocal类的子类。代替的每一个线程在一个ThreadLoca内部都有它自己的值,这个类同意访问对于一个线程的值,并且被那个线程创建的所有子线程。

    以上就是Java本地线程(ThreadLocal)的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!

    声明:本文原创发布php中文网,转载请注明出处,感谢您的尊重!如有疑问,请联系admin@php.cn处理
    专题推荐:Java,本地线程
    上一篇:Java的Volatile关键字详解 下一篇:Java 的多线程访问常见异常--fast-lost (快速失败 )
    大前端线上培训班

    相关文章推荐

    • 理解java8中java.util.function.*pojo反射新方法(附代码)• 浅析安卓app和微信授权登录及分享完整对接(代码分享)• 教你一招搞定时序数据库在Spring Boot中的使用• 一招教你使用java快速创建Map(代码分享)• PlayFramework 完整实现一个APP(十一)

    全部评论我要评论

  • 取消发布评论发送
  • 1/1

    PHP中文网