zoukankan      html  css  js  c++  java
  • 线程局部变量的使用

      共享数据是并发程序最核心的问题之一,对于继承了Thread类或者实现了Runnable接口的对象来说尤其重要。如果创建的对象是实现了Runable接口的类的实例,用它作为传入参数创建多个线程对象并启动这些线程,那么所有的线程将共享相同的属性。也就是说,如果你在一个线程中改变了一个属性,所有的线程都会被这个改变所影响。

      在某种情况下,这个对象的属性不需要被所有线程共享。Java并发API提供了一个干净的机制,即线程局部变量(Thread-Local Variable),其具有很好的性能。示例如下:

    import java.util.Date;
    import java.util.concurrent.TimeUnit;
    
    
    public class SafeTask implements Runnable {
        private static ThreadLocal<Date> startDate = new ThreadLocal<Date>(){
            @Override
            protected Date initialValue() {
                return new Date();
            }        
        };
        @Override
        public void run() {
            System.out.printf("Starting Thread: %s : %s
    ", Thread.currentThread().getId(), startDate.get());
            try {
                TimeUnit.SECONDS.sleep((int)Math.rint(Math.random()*10));
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            System.out.printf("Thread Finished: %s : %s
    ", Thread.currentThread().getId(), startDate.get());
        }
    
        public static void main(String[] args){
            SafeTask st = new SafeTask();
            try {
                for(int i=0;i<10;i++){
                    Thread t = new Thread(st);
                    t.start();
                    TimeUnit.SECONDS.sleep(2);
                }
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

      线程局部变量分别为每个线程存储了各自的属性值,并提供给每个线程使用。你可以使用get()方法读取这个值,并用set()方法设置这个值。如果线程是第一次访问线程局部变量,线程局部变量可能还没有为它存储值,这个时候initialValue()方法就会被调用,并且返回当前的时间值。

      线程局部变量也提供了remove()方法,用来访问这个变量的线程删除已经存储的值。Java并发API包含了InheritableThreadLocal类,如果一个线程是从其他某个线程中创建的,这个类将提供继承的值。如果一个线程A在线程局部变量已有值,当它创建其它某个线程B时,线程B的线程局部变量将跟线程A是一样的。你可以覆盖ChileValue()方法,这个方法用来初始化子线程在线程局部变量中的值。它使用父线程在线程局部变量中的值作为传入参数。

  • 相关阅读:
    20062007赛季欧洲冠军杯8强对阵情况
    常用的Javascript
    IFRAME 元素 | iframe 对象
    javascript技巧
    javascript部分事件解释
    正则表达式
    c#接口使用方法
    javascript日历控件
    DevExpress DXperience 的本地化(汉化)方法
    运算符总结
  • 原文地址:https://www.cnblogs.com/gaopeng527/p/4905865.html
Copyright © 2011-2022 走看看