本文是传智博客多线程视频的学习笔记。
原版本见
http://blog.csdn.net/dlf123321/article/details/42531979
ThreadLocal是一个和线程安全相关的类。
它能干什么?说的很模糊,咱们看一个图
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadScopeDataShare {
static private int data = 0;
public static void main(String[] args) {
ExecutorService threadPool = Executors.newCachedThreadPool();
for (int i = 0; i <2; i++) {
threadPool.execute(new Runnable() {
@Override
public void run() {
int data2= new Random().nextInt(100);
System.out.println(Thread.currentThread().getName()+" put "+data2);
data=data2;
try {
Thread.sleep(1000); //为什么要睡1秒 大家懂吗?
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new A().get();
new B().get();
}
});
}
threadPool.shutdown();
}
public static int getData() {
return data;
}
}
class A {
public int get() {
int data = ThreadScopeDataShare.getData();
System.out
.println("a "+Thread.currentThread().getName() + " getdata " + data);
return data;
}
}
class B {
public int get() {
int data = ThreadScopeDataShare.getData();
System.out
.println("b "+Thread.currentThread().getName() + " getdata " + data);
return data;
}
}
public class ThreadScopeShareData3 {
private static MapthreadData = new HashMap ();
public static void main(String[] args) {
ExecutorService threadPool = Executors.newCachedThreadPool();
for (int i = 0; i <2; i++) {
threadPool.execute(new Runnable() {
@Override
public void run() {
int data2= new Random().nextInt(100);
System.out.println(Thread.currentThread().getName()+" put "+data2);
threadData.put(Thread.currentThread(),data2);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
new A().get();
new B().get();
}
});
}
threadPool.shutdown();
}
static class A{
public void get(){
int data = threadData.get(Thread.currentThread());
System.out.println("A from " + Thread.currentThread().getName()
+ " get data :" + data);
}
}
//省略class B
}
运行结果
pool-1-thread-1 put 2
pool-1-thread-2 put 99
A from pool-1-thread-2 get data :99
A from pool-1-thread-1 get data :2
B from pool-1-thread-1 get data :2
B from pool-1-thread-2 get data :99
public class ThreadLocalTest {
private static ThreadLocalx = new ThreadLocal ();
public static void main(String[] args) {
for(int i=0;i<2;i++){
new Thread(new Runnable(){
@Override
public void run() {
int data = new Random().nextInt(500);
System.out.println(Thread.currentThread().getName()
+ " has put data :" + data);
x.set(data);
new A().get();
new B().get();
}
}).start();
}
}
static class A{
public void get(){
int data = x.get();
System.out.println("A from " + Thread.currentThread().getName()
+ " get data :" + data);
}
}
static class B{
public void get(){
int data = x.get();
System.out.println("B from " + Thread.currentThread().getName()
+ " get data :" + data);
}
}
}
如果变量没有关系,那就包装成一个map。
(当然一个线程如果要共享多个变量,那么分别设置为x,y也是可以的)
import java.util.Random;
public class ThreadLocalTest3 {
private static ThreadLocalmyThreadScopeData = new ThreadLocal ();
public static void main(String[] args) {
for (int i = 0; i <2; i++) {
new Thread(new Runnable() {
@Override
public void run() {
int data = new Random().nextInt(500);
MyThreadScopeData2 myData = new MyThreadScopeData2();
myData.setName("name" + data);
myData.setAge(data);
myThreadScopeData.set(myData);
new A().get();
new B().get();
}
}).start();
}
}
static class A {
public void get() {
MyThreadScopeData2 myData = myThreadScopeData.get();
System.out
.println("A from " + Thread.currentThread().getName()
+ " getMyData: " + myData.getName() + ","
+ myData.getAge());
}
}
//省略class B
}
class MyThreadScopeData2 {
private static ThreadLocalmap = new ThreadLocal ();
private String name;
private int age;
//省略get set
}
import java.util.Random;
public class ThreadLocalTest2 {
public static void main(String[] args) {
for(int i=0;i<2;i++){
new Thread(new Runnable(){
@Override
public void run() {
int data = new Random().nextInt(500);
MyThreadScopeData.getThreadInstance().setName("name" + data);
MyThreadScopeData.getThreadInstance().setAge(data);
new A().get();
new B().get();
}
}).start();
}
}
static class A{
public void get(){
MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();
System.out.println("A from " + Thread.currentThread().getName()
+ " getMyData: " + myData.getName() + "," +
myData.getAge());
}
}
//省略Class B
}
class MyThreadScopeData{
private MyThreadScopeData(){}
public static MyThreadScopeData getThreadInstance(){
MyThreadScopeData instance = map.get();
if(instance == null){
instance = new MyThreadScopeData();
map.set(instance);
}
return instance;
}
private static ThreadLocalmap =
new ThreadLocal();
private String name;
private int age;
//省略getset
}
参见:
http://blog.csdn.net/dlf123321/article/details/42531979