使用ThreadLocal类实现线程范围内的共享数据:
确保每个线程都有自己私有的变量和取到自己的变量。下面用ThreadLocal类实现,替代上节课中的map用法
代码:
package org.yla.thread; import java.util.Random; /** * 使用ThreadLocal类实现线程范围内的私有数据 * 替代上节课map的作用 * @author huo_chai_gun * 2014年12月18日下午3:25:35 */ public class ThreadLocalTest { private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); 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(100); System.out.println(Thread.currentThread().getName()+" has put data: "+data); //往local里面设置值 threadLocal.set(data); new A().get(); new B().get(); } }).start(); } } static class A{ public void get(){ int data =threadLocal.get(); System.out.println("A from "+Thread.currentThread().getName()+" has get data: "+data); } } static class B{ public void get(){ int data =threadLocal.get(); System.out.println("B from "+Thread.currentThread().getName()+" has get data: "+data); } } }
Thread-0 has put data: 48 Thread-1 has put data: 95 A from Thread-1 has get data: 95 A from Thread-0 has get data: 48 B from Thread-0 has get data: 48 B from Thread-1 has get data: 95
假设我们有多个线程需要范围内的共享数据,那么我们的代码就得改成下面的形式了:思路是把 其他属性的值打包成一个类
package org.yla.thread; import java.util.Random; /** * 使用ThreadLocal类实现线程范围内的私有数据 * 替代上节课map的作用 * @author huo_chai_gun * 2014年12月18日下午3:25:35 */ public class ThreadLocalTest { private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); private static ThreadLocal<MyThreadLocalScopeDate> myLocalScopeData = new ThreadLocal<MyThreadLocalScopeDate>(); 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(100); System.out.println(Thread.currentThread().getName()+" has put data: "+data); //往local里面设置值 threadLocal.set(data); MyThreadLocalScopeDate scopeDate = new MyThreadLocalScopeDate(); scopeDate.setName("name "+data); scopeDate.setAge(data); myLocalScopeData.set(scopeDate); new A().get(); new B().get(); } }).start(); } } static class A{ public void get(){ int data =threadLocal.get(); System.out.println("A from "+Thread.currentThread().getName()+" has get data: "+data); MyThreadLocalScopeDate scopeDate=myLocalScopeData.get(); System.out.println("A from "+Thread.currentThread().getName()+" has get MyThreadLocalScopeDate name: "+scopeDate.getName()+" , age: "+scopeDate.getAge()); } } static class B{ public void get(){ int data =threadLocal.get(); System.out.println("B from "+Thread.currentThread().getName()+" has get data: "+data); MyThreadLocalScopeDate scopeDate=myLocalScopeData.get(); System.out.println("B from "+Thread.currentThread().getName()+" has get MyThreadLocalScopeDate name: "+scopeDate.getName()+" , age: "+scopeDate.getAge()); } } } class MyThreadLocalScopeDate{ private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
Thread-0 has put data: 2 Thread-1 has put data: 94 A from Thread-1 has get data: 94 A from Thread-0 has get data: 2 A from Thread-1 has get MyThreadLocalScopeDate name: name 94 , age: 94 A from Thread-0 has get MyThreadLocalScopeDate name: name 2 , age: 2 B from Thread-1 has get data: 94 B from Thread-0 has get data: 2 B from Thread-1 has get MyThreadLocalScopeDate name: name 94 , age: 94 B from Thread-0 has get MyThreadLocalScopeDate name: name 2 , age: 2
上面的代码虽然实现了功能,但是代码实现是很垃圾,一个线程有一个实例,那么多个线程就有多个实例,所以我们还要对代码进行修改:
思路:利用单例模式 实现线程范围内的共享数据 这样子就永远只有一个对象 但是每个线程拿这个对象的时后我们让他显示互斥效果 这样子就节省了内容的消耗 并且外部调用的时候 还看不见ThreadLocal对这个对象进行了封装
真正开发中应该这么设计比较好【注意】
代码:
package org.yla.thread; import java.util.Random; /** * 使用ThreadLocal类实现线程范围内的私有数据 * @author huo_chai_gun * 2014年12月18日下午3:25:35 */ public class ThreadLocalTest { private static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); 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(100); System.out.println(Thread.currentThread().getName()+" has put data: "+data); //往local里面设置值 threadLocal.set(data); //获取自己线程的MyThreadLocalScopeDate实例对象 MyThreadLocalScopeDate myData = MyThreadLocalScopeDate.getThreadInstance(); myData.setName("name"+data); myData.setAge(data); new A().get(); new B().get(); } }).start(); } } static class A{ public void get(){ int data =threadLocal.get(); System.out.println("A from "+Thread.currentThread().getName()+" has get data: "+data); MyThreadLocalScopeDate myData = MyThreadLocalScopeDate.getThreadInstance(); System.out.println("A from "+Thread.currentThread().getName()+" has get MyThreadLocalScopeDate name: "+myData.getName()+" , age: "+myData.getAge()); } } static class B{ public void get(){ int data =threadLocal.get(); System.out.println("B from "+Thread.currentThread().getName()+" has get data: "+data); MyThreadLocalScopeDate myData = MyThreadLocalScopeDate.getThreadInstance(); System.out.println("B from "+Thread.currentThread().getName()+" has get MyThreadLocalScopeDate name: "+myData.getName()+" , age: "+myData.getAge()); } } } class MyThreadLocalScopeDate{//单例模式 private MyThreadLocalScopeDate(){};//构造方法私有化 private static ThreadLocal<MyThreadLocalScopeDate> map = new ThreadLocal<MyThreadLocalScopeDate>();//封装MyThreadLocalScopeDate是线程实现范围内共享 //思考AB两个线程过来的情况 自己分析 AB都需要的自己的对象 没有关系 所以不需要同步 如果有关系就需要同步了 public static /*synchronized*/MyThreadLocalScopeDate getThreadInstance(){ MyThreadLocalScopeDate instance =map.get(); if(instance==null){ instance = new MyThreadLocalScopeDate(); map.set(instance); } return instance; } private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
Thread-0 has put data: 24 Thread-1 has put data: 13 A from Thread-1 has get data: 13 A from Thread-1 has get MyThreadLocalScopeDate name: name13 , age: 13 A from Thread-0 has get data: 24 A from Thread-0 has get MyThreadLocalScopeDate name: name24 , age: 24 B from Thread-1 has get data: 13 B from Thread-1 has get MyThreadLocalScopeDate name: name13 , age: 13 B from Thread-0 has get data: 24 B from Thread-0 has get MyThreadLocalScopeDate name: name24 , age: 24
原文地址:http://blog.csdn.net/huo_chai_gun/article/details/42006345