线程范围内数据共享 【小K从搞定时鞭炮被迫改名小钟穿越到唐朝小赚一把后,最近一直木有现身了,不知道他又在搞什么名堂,或者是时光机将他带到了不对的地方 ...参见Timer初识、Timer补充】 【醒醒吧,孩纸,麻麻叫你回家吃饭啦~故事暂停告一段落,只是木有广告噢,广告公司还没有瞄上我在跟苗子呢,继续我的初衷----分享为王】 ...... 【只见袁老师站在一个还没有开学的学校教室里,木有学生,木有观众,开始了自己的孤单课程之旅,也不知道是第几站,只知道这站叫《线程范围内数据共享》】 【反正没有学生,也不要多说话,袁老师一气之下将黑板涂鸦满了】
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
/**
* 线程空间数据共享,在银行转账事务中有很大的作用
*
* @author ysjian
* @version 1.0
* @email ysjian_pingcx@126.com
* @QQ 646633781
* @telephone 18192235667
* @csdnBlog http://blog.csdn.net/ysjian_pingcx
* @createTime 2014-1-5
* @copyRight Merit
*/
public class ThreadScopeShare {
/**
* 存放线程数据
*/
private static Map
threadData = new HashMap<>();
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 3; i++) {
new Thread(new Runnable() {
@Override
public void run() {
int data = new Random().nextInt();
// 将当前线程和数据绑定
threadData.put(Thread.currentThread(), data);
new Student1().getData();
new Student2().getData();
new Student3().getData();
}
}).start();
}
}
private static class Student1 {
public void getData() {
System.out.println("Student1-->" + Thread.currentThread().getName()
+ "-->get data-->" + threadData.get(Thread.currentThread()));
}
}
private static class Student2 {
public void getData() {
System.out.println("Student2-->" + Thread.currentThread().getName()
+ "-->get data-->" + threadData.get(Thread.currentThread()));
}
}
private static class Student3 {
public void getData() {
System.out.println("Student3-->" + Thread.currentThread().getName()
+ "-->get data-->" + threadData.get(Thread.currentThread()));
}
}
}
【哎,看来袁老师太渴望有学生了,搞了三个私有的还是静态的学生,伤不起啊。看来黑板也不大,代码都不空行,那么紧凑(
下载参考
Java编码规范)】 袁老师:嗯...代码有些紧凑啊,大家(自创的三个学生)集中注意力了,这个代码比较简单,摔点精粹的:这个思想就是用一个HashMap容器来保存线程对象和该线程对应的数据,然后在取数据的时候根据key,也就是线程对象去去该线程对应的数据,从结果里看出,不同的学生能够从相同的线程取出相同的数据,而同一个学生从不同的线程中取出的数据也不同,这就是线程范围内数据共享的简单实现。 【边说袁老师在脑海构想这个程序的运行结果】 运行结果:
Student1-->Thread-1-->get data-->-1222988110
Student1-->Thread-2-->get data-->1857950365
Student1-->Thread-0-->get data-->242884708
Student2-->Thread-1-->get data-->-1222988110
Student2-->Thread-0-->get data-->242884708
Student2-->Thread-2-->get data-->1857950365
Student3-->Thread-1-->get data-->-1222988110
Student3-->Thread-2-->get data-->1857950365
Student3-->Thread-0-->get data-->242884708
【突然,袁老师从幻境中醒来,有些伤感,其实下面一个学生都没有,酝酿片刻,之间袁老师面露一丝笑容,心想:不要学生我也可以达到目的。之间袁老师霹雳哗啦的将黑板擦干净,准备下一轮的涂鸦...】 【不一会儿,黑压压的一片】 ThreadLocal粉末登场:
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 线程共享类的实现
*
* @author ysjian
* @version 1.0
* @email ysjian_pingcx@126.com
* @QQ 646633781
* @telephone 18192235667
* @csdnBlog http://blog.csdn.net/ysjian_pingcx
* @createTime 2014-1-6
* @copyRight Merit
*/
public class ThreadLocalDemo {
/**
* 一个ThreadLocal只能存放一个变量,需要放多个信息的时候,利用javaBena封装
*/
private static ThreadLocal
local = new ThreadLocal<>();
private static class A {
public void getData() {
System.out.println("A-->" + Thread.currentThread().getName()
+ "-->get data-->" + local.get());
}
}
private static class B {
public void getData() {
System.out.println("B-->" + Thread.currentThread().getName()
+ "-->get data-->" + local.get());
}
}
private static class C {
public void getData() {
System.out.println("C-->" + Thread.currentThread().getName()
+ "-->get data-->" + local.get());
}
}
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(3);
for (int i = 0; i < 3; i++) {
service.execute(new Runnable() {
@Override
public void run() {
int data = new Random().nextInt(10);
local.set(data);
new A().getData();
new B().getData();
new C().getData();
}
});
}
service.shutdown();
}
}
【仔细一看,其实还是三个类,只不过袁老师改成了A、B、C了,换汤不换药啊,同情一下他吧,不跟他计较这个了。这个用上了ThreadLocal类,跟上一个自己实现的差别不大,只不过更体现了Java的封装性。】 袁老师:... 【袁老师刚要说点什么,话刚到嘴边,却拿起黑板擦打太极似的将黑板擦掉,然后扔掉黑板擦开始新的涂鸦,他似乎有点激动,看看他能够弄出个啥名堂】 ThreadLocalData:
/**
* 线程共享,经典的单例实现
*
* @author ysjian
* @version 1.0
* @email ysjian_pingcx@126.com
* @QQ 646633781
* @telephone 18192235667
* @csdnBlog http://blog.csdn.net/ysjian_pingcx
* @createTime 2014-1-6
* @copyRight Merit
*/
class ThreadLocalData {
private String name;
private int id;
private ThreadLocalData() {}
private