线程范围内的数据共享(ThreadLocal应用)
自定义实现
package org.xyz.java.thread.v5.threadlocal;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* 自定义模拟来实现线程范围内数据共享
* @author kevin.chen
*
*/
public class ThreadScopeShareData {
private static Map<Thread,Integer> map = new HashMap<Thread,Integer>();
public static void main(String[] args) {
// 创建多个线程
for(int i=0; i<3; i++) {
new Thread(new Runnable() {
@Override
public void run() {
int data = new Random().nextInt();
System.out.println(Thread.currentThread().getName() + " put data :" + data);
// 将当前线程对象和数据放入到map中
map.put(Thread.currentThread(), data);
// A取数据
new A().get();
// B取数据
new B().get();
}
}).start();
}
}
static class A {
public void get() {
int data = map.get(Thread.currentThread());
System.out.println("now in A [" + Thread.currentThread().getName() + "] data : "+ data);
}
}
static class B {
public void get() {
int data = map.get(Thread.currentThread());
System.out.println("now in B [" + Thread.currentThread().getName() + "] data : "+ data);
}
}
}
ThreadLocal实现
存储单个变量
package org.xyz.java.thread.v5.threadlocal;
import java.util.Random;
/**
* 使用ThreadLocal来实现线程范围内数据共享
* 存储单个数据
* @author kevin.chen
*
*/
public class ThreadLocalTest {
private static ThreadLocal<Integer> map = new ThreadLocal<Integer>();
public static void main(String[] args) {
// 创建多个线程
for(int i=0; i<3; i++) {
new Thread(new Runnable() {
@Override
public void run() {
int data = new Random().nextInt();
System.out.println(Thread.currentThread().getName() + " put data :" + data);
// 将当前线程对象和数据进行绑定
map.set(data);
// C取数据
new C().get();
// D取数据
new D().get();
}
}).start();
}
}
static class C {
public void get() {
int data = map.get();
System.out.println("now in C [" + Thread.currentThread().getName() + "] data : "+ data);
}
}
static class D {
public void get() {
int data = map.get();
System.out.println("now in D [" + Thread.currentThread().getName() + "] data : "+ data);
}
}
}
存储多个变量数据
package org.xyz.java.thread.v5.threadlocal;
import java.util.Random;
/**
* 使用ThreadLocal来实现线程范围内数据共享
* 存储多个数据 (此方式不够优雅,对比ThreadLocalTest2的改进优雅版)
* @author kevin.chen
*
*/
public class ThreadLocalTest1 {
private static ThreadLocal<MyData> map = new ThreadLocal<MyData>();
public static void main(String[] args) {
// 创建多个线程
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {
@Override
public void run() {
int data = new Random().nextInt(100);
String name = "No-" + data;
String pwd = "Pwd-" + data;
System.out.println(Thread.currentThread().getName() + " put name :" + name + ",pwd :" + pwd + ",age :" + data);
// 给对象赋值
MyData md = new MyData();
md.setName(name);
md.setPwd(pwd);
md.setAge(data);
// 将当前线程对象和数据进行绑定
map.set(md);
// C取数据
new C().get();
// D取数据
new D().get();
}
}).start();
}
}
static class C {
public void get() {
MyData data = map.get();
System.out.println("now in C [" + Thread.currentThread().getName() + "] data : " + data);
}
}
static class D {
public void get() {
MyData data = map.get();
System.out.println("now in D [" + Thread.currentThread().getName() + "] data : " + data);
}
}
}
class MyData {
private String name;
private String pwd;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "MyData [name=" + name + ", pwd=" + pwd + ", age=" + age + "]";
}
}
ThreadLocal实现(优雅版)
package org.xyz.java.thread.v5.threadlocal;
import java.util.Random;
/**
* 使用ThreadLocal来实现线程范围内数据共享
* 存储多个数据 (此方式比较优雅,对比ThreadLocalTest1版)
* @author kevin.chen
*
*/
public class ThreadLocalTest2 {
public static void main(String[] args) {
// 创建多个线程
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {
@Override
public void run() {
int data = new Random().nextInt(100);
String name = "No-" + data;
String pwd = "Pwd-" + data;
System.out.println(Thread.currentThread().getName() + " put name :" + name + ",pwd :" + pwd + ",age :" + data);
// 给对象赋值
MyData2 md = MyData2.getThreadInstance();
md.setName(name);
md.setPwd(pwd);
md.setAge(data);
// 这里就不用再讲对象和当前线程进行绑定了,因为在获取对象的时候就已经是获取了和当前线程绑定的对象了
// E取数据
new E().get();
// F取数据
new F().get();
}
}).start();
}
}
static class E {
public void get() {
// 这里直接获取对象即可,相当优雅
MyData2 data = MyData2.getThreadInstance();
System.out.println("now in E [" + Thread.currentThread().getName() + "] data : " + data);
}
}
static class F {
public void get() {
// 这里直接获取对象即可,相当优雅
MyData2 data = MyData2.getThreadInstance();
System.out.println("now in F [" + Thread.currentThread().getName() + "] data : " + data);
}
}
}
class MyData2 {
// 将ThreadLocal定义为类变量,屏蔽使用方对ThreadLocal的引用
private static ThreadLocal<MyData2> map = new ThreadLocal<MyData2>();
// 单例
private MyData2() {}
public static MyData2 getThreadInstance() {
// 线程ThreadLocal中获取和当前线程绑定的对象
MyData2 data = map.get();
// 如果对象为空,则创建新对象,并和线程绑定
if(data == null) {
data = new MyData2();
// 将对象和线程绑定
map.set(data);
}
return data;
}
private String name;
private String pwd;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "MyData [name=" + name + ", pwd=" + pwd + ", age=" + age + "]";
}
}