您的位置:首页 > 编程语言 > Java开发

JAVA中ThreadLocal用法介绍

2018-01-11 00:00 162 查看

概述

ThreadLocal
看名字好像是一个Thread的实现,其实并不是这样的,ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物,因为访问某个变量(通过其 get 或 set 方法)的每个线程都有自己的局部变量,它独立于变量的初始化副本。ThreadLocal 实例通常是类中的 private static 字段,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联。

线程局部变量其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,使每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。

从线程的角度看,每个线程都保持一个对其线程局部变量副本的隐式引用,只要线程是活动的并且 ThreadLocal 实例是可访问的;在线程消失之后,其线程局部实例的所有副本都会被垃圾回收(除非存在对这些副本的其他引用)。

API

构造方法摘要

方法名说明
ThreadLocal()创建一个线程本地变量

方法摘要

返回值方法名说明
Tget()返回此线程局部变量的当前线程副本中的值
protected TinitialValue()返回此线程局部变量的当前线程的“初始值”
voidremove()移除此线程局部变量当前线程的值
voidset(T value)将此线程局部变量的当前线程副本中的值设置为指定值

使用示例

import java.util.Random;

/**
* ThreadLocal测试
*
* @author jianggujin
*
*/
public class ThreadLocalDemo implements Runnable
{
private final static ThreadLocal<People> threadLocal = new ThreadLocal<People>();

public static void main(String[] agrs)
{
ThreadLocalDemo td = new ThreadLocalDemo();
Thread t1 = new Thread(td);
Thread t2 = new Thread(td);
t1.start();
t2.start();
}

public void run()
{
accessStudent();
}

public void accessStudent()
{
// 获取当前线程的名字
String currentThreadName = Thread.currentThread().getName();
System.out.println(currentThreadName + " is running!");
// 产生一个随机数并打印
Random random = new Random();
int age = random.nextInt(100);
System.out.println("thread " + currentThreadName + " set age to:" + age);
People people = getPeople();
people.setAge(age);
System.out.println("thread " + currentThreadName + " first read age is:"
+ people.getAge());
try
{
Thread.sleep(500);
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
System.out.println("thread " + currentThreadName + " second read age is:"
+ people.getAge());
}

protected People getPeople()
{
People people = threadLocal.get();
// 线程首次执行此方法的时候,threadLocal.get()肯定为null
if (people == null)
{
// 创建一个对象,并保存到本地线程变量threadLocal中
people = new People();
threadLocal.set(people);
}
return people;
}
}

class People
{
private int age = 0;

public int getAge()
{
return this.age;
}

public void setAge(int age)
{
this.age = age;
}
}


总结

ThreadLocal使用场合主要解决多线程中数据数据因并发产生不一致问题。ThreadLocal为每个线程的中并发访问的数据提供一个副本,通过访问副本来运行业务,这样的结果是耗费了内存,但是大大减少了线程同步所带来性能消耗(空间换时间),也减少了线程并发控制的复杂度。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Threadlocal