Java中如何实现单个线程范围内的数据共享
2014-05-01 16:10
886 查看
单个线程范围内的数据共享,就是确保当前的线程在执行的过程中,各个模块所引用的数据是一份,且所引用的数据不会因为其他线程的操作而变化。
以下是一段没有达到线程内数据共享的代码(参考自传智播客视频)
控制台输出:
根据控制台的结果,可以看出,由于定义了static的变量存储数据,那么当线程2更改了data数据后,线程1中 A模块和B模块取出的和当初线程1放入的不是一个值,如何解决这个问题呢?见如下代码:
一、使用全局的map变量实现
二、使用ThreadLocal类,实现单个线程范围内 单个变量的数据共享
三、使用ThreadLocal实现 单个线程内 多个变量的数据共享
实现多个数据的共享可以使用Map去存放数据,这里就不说了 就是把ThreadLocal中的Integer替换成Map即可,主要贴一下使用对象存储多个变量的代码实现
①创建一个用于存放共享数据的类
②操作共享数据
以下是一段没有达到线程内数据共享的代码(参考自传智播客视频)
public class ThreadScopeShareData { //用于存放随机产生的数据 static int data = 0; public static void main(String[] args) { //线程1 new Thread(new Runnable() { @Override public void run() { data = new Random().nextInt(1000); System.out.println(Thread.currentThread().getName() + "has put data:" + data); //使用A对象输出数据 new A().getData(); //使用B对象输出数据 new B().getData(); } }).start(); //线程2 new Thread(new Runnable() { @Override public void run() { data = new Random().nextInt(1000); System.out.println(Thread.currentThread().getName() + "has put data:" + data); //使用A对象输出数据 new A().getData(); //使用B对象输出数据 new B().getData(); } }).start(); } } class A { public void getData() { System.out.println("A :" + Thread.currentThread().getName() + ": get data value:" + ThreadScopeShareData.data); } } class B { public void getData() { System.out.println("B :" + Thread.currentThread().getName() + ": get data value:" + ThreadScopeShareData.data); } }
控制台输出:
根据控制台的结果,可以看出,由于定义了static的变量存储数据,那么当线程2更改了data数据后,线程1中 A模块和B模块取出的和当初线程1放入的不是一个值,如何解决这个问题呢?见如下代码:
一、使用全局的map变量实现
public class ThreadScopeShareData { //用于存放随机产生的数据 //static int data = 0; /* * 使用map类型的变量取代int类型的变量 */ static Map<Thread, Integer> map = new HashMap<Thread, Integer>(); public static void main(String[] args) { //线程1 new Thread(new Runnable() { @Override public void run() { //data = new Random().nextInt(1000); int data = new Random().nextInt(1000); //用当前线程作为key,将当前线程产生的随机数,存入map中 map.put(Thread.currentThread(), data); System.out.println(Thread.currentThread().getName() + " has put data:" + data); //使用A对象输出数据 new A().getData(); //使用B对象输出数据 new B().getData(); } }).start(); //线程2 new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(1000); //用当前线程作为key,将当前线程产生的随机数,存入map中 map.put(Thread.currentThread(), data); System.out.println(Thread.currentThread().getName() + " has put data:" + data); //使用A对象输出数据 new A().getData(); //使用B对象输出数据 new B().getData(); } }).start(); } } class A { public void getData() { //使用当前线程作为map的key去取出map中对应的value System.out.println("A :" + Thread.currentThread().getName() + ": get data value:" + ThreadScopeShareData.map.get(Thread.currentThread())); } } class B { public void getData() { //使用当前线程作为map的key去取出map中对应的value System.out.println("B :" + Thread.currentThread().getName() + ": get data value:" + ThreadScopeShareData.map.get(Thread.currentThread())); } }
二、使用ThreadLocal类,实现单个线程范围内 单个变量的数据共享
public class ThreadScopeShareData { /* * 使用ThreadLocal */ static ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); public static void main(String[] args) { //线程1 new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(1000); //将当前线程产生的随机数,存入threadLocal中 threadLocal.set(data); System.out.println(Thread.currentThread().getName() + " has put data:" + data); //使用A对象输出数据 new A().getData(); //使用B对象输出数据 new B().getData(); } }).start(); //线程2 new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(1000); //将当前线程产生的随机数,存入threadLocal中 threadLocal.set(data); System.out.println(Thread.currentThread().getName() + " has put data:" + data); //使用A对象输出数据 new A().getData(); //使用B对象输出数据 new B().getData(); } }).start(); } } class A { public void getData() { //从threadLocal中取出value System.out.println("A :" + Thread.currentThread().getName() + ": get data value:" + ThreadScopeShareData.threadLocal.get()); } } class B { public void getData() { //从threadLocal中取出value System.out.println("B :" + Thread.currentThread().getName() + ": get data value:" + ThreadScopeShareData.threadLocal.get()); } }
三、使用ThreadLocal实现 单个线程内 多个变量的数据共享
实现多个数据的共享可以使用Map去存放数据,这里就不说了 就是把ThreadLocal中的Integer替换成Map即可,主要贴一下使用对象存储多个变量的代码实现
①创建一个用于存放共享数据的类
/** * 存放共享数据的对象 * @author *** * */ class ShareDataObj { /** * threadLocal */ private static ThreadLocal<ShareDataObj> threadLocal = new ThreadLocal<ShareDataObj>(); private ShareDataObj() { } /** * 返回从ThreadLocal中取出当前线程的ShareDataObj对象 * @return */ public static ShareDataObj getInstance4currentThread() { //从threadLocal变量中取出当前线程的ShareDataObj对象 ShareDataObj dataObj = threadLocal.get(); if(dataObj == null) { //1、创建一个新的对象 dataObj = new ShareDataObj(); //2、将创建的对象放入ShareDataObj对象中 threadLocal.set(dataObj); } return dataObj; } //data1 private int data1; //data2 private String data2; public int getData1() { return data1; } public void setData1(int data1) { this.data1 = data1; } public String getData2() { return data2; } public void setData2(String data2) { this.data2 = data2; } }
②操作共享数据
public class ThreadScopeShareData { public static void main(String[] args) { //线程1 new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(1000); //将当前线程产生的随机数,放入数据共享对象中 ShareDataObj.getInstance4currentThread().setData1(data); ShareDataObj.getInstance4currentThread().setData2("str-" + data); System.out.println(Thread.currentThread().getName() + " has put data:" + data); //使用A对象输出数据 new A().getData(); //使用B对象输出数据 new B().getData(); } }).start(); //线程2 new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(1000); //将当前线程产生的随机数,放入数据共享对象中 ShareDataObj.getInstance4currentThread().setData1(data); ShareDataObj.getInstance4currentThread().setData2("str-" + data); System.out.println(Thread.currentThread().getName() + " has put data:" + data); //使用A对象输出数据 new A().getData(); //使用B对象输出数据 new B().getData(); } }).start(); } } class A { public void getData() { //从ShareDataObj中取出当前线程的数据共享对象 System.out.println("A :" + Thread.currentThread().getName() + ": get data1:" + ShareDataObj.getInstance4currentThread().getData1() + ", get data2:" + ShareDataObj.getInstance4currentThread().getData2()); } } class B { public void getData() { //从ShareDataObj中取出当前线程的数据共享对象 System.out.println("B :" + Thread.currentThread().getName() + ": get data1:" + ShareDataObj.getInstance4currentThread().getData1() + ", get data2:" + ShareDataObj.getInstance4currentThread().getData2()); } }
相关文章推荐
- 黑马程序员---java中如何实现线程范围内共享数据
- Java基础——ThreadLocal实现线程范围内的数据共享
- java-线程-用ThreadLocal类实现线程范围内的数据共享
- ThreadLocal实现:java线程范围内的共享数据,线程外独立
- ThreadLocal实现线程范围内的数据共享
- 【java并发】线程范围内共享数据
- java多线程:5、线程范围内的数据共享_ThreadLocal
- Java高并发编程:线程范围内共享数据
- ThreadLocal类实现线程范围内数据共享
- Java基础——线程范围内的共享数据概念和作用
- java多线程:16、阻塞队列【BlockingQueue】实现线程数据共享的效果
- java高级之线程范围内的共享数据
- Java基础:多线程之线程范围内的数据共享ThreadLocal
- Java不同线程之间实现数据共享
- ThreadLocal实现线程范围内模块之间共享数据及线程间数据独立
- java 多线程 day05 线程范围内的数据共享
- Java Web 中application(应用级) session(会话级) request(请求级)如何实现数据共享
- Java死锁和线程范围内共享数据
- 在一个程序中需要用到全局变量(在多个class之间共享数据),请问如何定义具有这种功能的变量?或者是否有其他的方法解决多个class之间的数据共享(尽量简单实现)。 首先应该明确 Java中没有全局变
- java多线程与线程并发四:线程范围内的共享数据