-
也就是说这个类给线程提供了一个本地变量,这个变量是该线程自己拥有的。在该线程存活和ThreadLocal实例能访问的时候,保存了对这个变量副本的引用.当线程消失的时候,所有的本地实例都会被GC。并且建议我们ThreadLocal最好是 private static 修饰的成员
-
ThreadLocal和Synchonized区别:
都用于解决多线程并发访问。
Synchronized用于线程间的数据共享(使变量或代码块在某一时该只能被一个线程访问),是一种以延长访问时间来换取线程安全性的策略;
而ThreadLocal则用于线程间的数据隔离(为每一个线程都提供了变量的副本),是一种以空间来换取线程安全性的策略
package com.coshaho.reflect;
/**
* ThreadLocal用法
* @author coshaho
*
*/
public class MyThreadLocal
{
private static final ThreadLocal<Object> threadLocal = new ThreadLocal<Object>(){
/**
* ThreadLocal没有被当前线程赋值时或当前线程刚调用remove方法后调用get方法,返回此方法值
*/
@Override
protected Object initialValue()
{
System.out.println("调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!");
return null;
}
};
public static void main(String[] args)
{
new Thread(new MyIntegerTask("IntegerTask1")).start();
new Thread(new MyStringTask("StringTask1")).start();
new Thread(new MyIntegerTask("IntegerTask2")).start();
new Thread(new MyStringTask("StringTask2")).start();
}
public static class MyIntegerTask implements Runnable
{
private String name;
MyIntegerTask(String name)
{
this.name = name;
}
@Override
public void run()
{
for(int i = 0; i < 5; i++)
{
// ThreadLocal.get方法获取线程变量
if(null == MyThreadLocal.threadLocal.get())
{
// ThreadLocal.et方法设置线程变量
MyThreadLocal.threadLocal.set(0);
System.out.println("线程" + name + ": 0");
}
else
{
int num = (Integer)MyThreadLocal.threadLocal.get();
MyThreadLocal.threadLocal.set(num + 1);
System.out.println("线程" + name + ": " + MyThreadLocal.threadLocal.get());
if(i == 3)
{
MyThreadLocal.threadLocal.remove();
}
}
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
public static class MyStringTask implements Runnable
{
private String name;
MyStringTask(String name)
{
this.name = name;
}
@Override
public void run()
{
for(int i = 0; i < 5; i++)
{
if(null == MyThreadLocal.threadLocal.get())
{
MyThreadLocal.threadLocal.set("a");
System.out.println("线程" + name + ": a");
}
else
{
String str = (String)MyThreadLocal.threadLocal.get();
MyThreadLocal.threadLocal.set(str + "a");
System.out.println("线程" + name + ": " + MyThreadLocal.threadLocal.get());
}
try
{
Thread.sleep(800);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}
<strong>}
</strong>
运行结果:
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
线程IntegerTask1:
0
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
线程IntegerTask2:
0
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
线程StringTask1: a
线程StringTask2: a
线程StringTask1: aa
线程StringTask2: aa
线程IntegerTask1:
1
线程IntegerTask2:
1
线程StringTask1: aaa
线程StringTask2: aaa
线程IntegerTask2:
2
线程IntegerTask1:
2
线程StringTask2: aaaa
线程StringTask1: aaaa
线程IntegerTask2:
3
线程IntegerTask1:
3
线程StringTask1: aaaaa
线程StringTask2: aaaaa
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
线程IntegerTask2:
0
调用get方法时,当前线程共享变量没有设置,调用initialValue获取默认值!
线程IntegerTask1:
0