1.9线程局部变量的使用

来源:互联网 发布:dwz前端框架 知乎 编辑:程序博客网 时间:2024/04/28 09:35

如果创建的对象是实现了Runnable接口的类的实例,并作为参数传给给多个线程对象并启动这些线程,那么所有的线程将共享共同的属性。在有的时候,如果不想某些属性被共享,那么就需要 使用Java提供的线程局部变量了。

首先看一下不使用线程局部变量的例子:

1.创建一个实现Runnable接口的UnSafeTask类

import java.util.Date;import java.util.concurrent.TimeUnit;public class UnsafeTask implements Runnable{    private Date startDate;    @Override    public void run() {        // TODO Auto-generated method stub        startDate=new Date();        System.out.printf("The thread %s:%s\n",Thread.currentThread().getId(),startDate);        try        {            TimeUnit.SECONDS.sleep((int)Math.rint(Math.random()*10));        }catch(InterruptedException e)        {            e.printStackTrace();        }        System.out.printf("thread finished:%s:%s\n", Thread.currentThread().getId(),startDate);    }}

2.主类的实现

import java.util.concurrent.TimeUnit;public class Core {    public static void main(String[] args) {        // TODO Auto-generated method stub        UnsafeTask task=new UnsafeTask();        for(int i=0;i<10;i++)        {            Thread thread=new Thread(task);            thread.start();            try            {                TimeUnit.SECONDS.sleep(2);            }catch(InterruptedException e)            {                e.printStackTrace();            }        }    }}

3.运行结果
这里写图片描述
可以清楚地看到有些进程显示的结束时间竟然一样,这并不是我们的本意,所以在下一个例子中需要使用局部变量了。

接下来是使用线程局部变量的例子:

1.实现Runnable接口的SafeTask类

import java.util.Date;import java.util.concurrent.TimeUnit;public class SafeTask implements Runnable{    //使用线程局部变量    private static ThreadLocal<Date> startDate=new ThreadLocal<Date>()            {                    protected Date initialValue()                    {                        return new Date();                    }            };            @Override            public void run() {                // TODO Auto-generated method stub                System.out.printf("The thread %s:%s\n",Thread.currentThread().getId(),startDate.get());                try                {                    TimeUnit.SECONDS.sleep((int)Math.rint(Math.random()*10));                }catch(InterruptedException e)                {                    e.printStackTrace();                }                System.out.printf("thread finished:%s:%s\n", Thread.currentThread().getId(),startDate.get());            }}

2.主类的实现

import java.util.concurrent.TimeUnit;public class SafeCore {    public static void main(String[] args) {        // TODO Auto-generated method stub        SafeTask task=new SafeTask();        for(int i=0;i<10;i++)        {            Thread thread=new Thread(task);            thread.start();            try            {                TimeUnit.SECONDS.sleep(2);            }catch(InterruptedException e)            {                e.printStackTrace();            }        }    }}

3.运行结果
这里写图片描述

可以看到在使用了线程局部变量之后,上一个例子的问题就消失不见了。

0 0
原创粉丝点击