android 线程范围内共享变量以及ThreadLocal的使用
2015-02-05 22:44
696 查看
线程在java中是一个重头戏,算是比较难的一快,特别是并发哪一块,关于并发这一块,项目上几乎也没用到,今天是讲线程范围内的共享变量,突然听到这个概念,可能心里有点发愣,打个简单比方:有三个线程,每一个产生一个数据,有三个模块分别取获取每个线程产生的数据,在java中其实已经有现成的类给我们解决了此方案 哪就是ThreadLoacl类,我们先不用java提供的类先手动解决下
打印结果:
看到这个结果 此时心都凉了,怎么和我预期的效果不一样,其实仔细看代码不能发现这是线程安全问题导致的,稍微分析一下就知道了程序运行是这样的,
发现程序并不是按照我们正常从一而终这样顺序运行的,每当线程运行到给data变量赋值时,另外一个线程就进来了,依次类推,这样会导致前生成的data变量值会被后的值覆盖,哪我们就换个方案,我们把每一个线程产生的数据和这个线程一一对应,哪就用到集合存储了,代码修改后如下:
发现这个方案也是有问题的,问题出在哪呢?和之前分析的到底一样,哪现在怎么改呢?此刻无限的沉思之中,怎么办?还有什么办法呢?其实只要解决一个问题 就可以把所有的问题解决掉,哪就是变量data属于每个线程自己的属性,这个时候就是考察你基本功好不好的关键时刻了,其实只要把data变量不要做成类变量就可以了,
int data = new Random().nextInt();
好了问题解决了,现在改用java给我们提供好的ThreadLocal类
package com.kge; import java.util.Random; public class ThreadLocalDemo { private static int data = 0; public static void main(String[] args) { for(int i=0;i<4;i++){ new Thread(new Runnable() { @Override public void run() { data = new Random().nextInt(); System.out.println(Thread.currentThread().getName()+"has put data:"+data); new A().get(); new B().get(); } }){}.start(); } } static class A{ public void get(){ System.out.println("A from"+Thread.currentThread().getName()+"data="+data); } } static class B{ public void get(){ System.out.println("B from"+Thread.currentThread().getName()+"data="+data); } } }
打印结果:
看到这个结果 此时心都凉了,怎么和我预期的效果不一样,其实仔细看代码不能发现这是线程安全问题导致的,稍微分析一下就知道了程序运行是这样的,
发现程序并不是按照我们正常从一而终这样顺序运行的,每当线程运行到给data变量赋值时,另外一个线程就进来了,依次类推,这样会导致前生成的data变量值会被后的值覆盖,哪我们就换个方案,我们把每一个线程产生的数据和这个线程一一对应,哪就用到集合存储了,代码修改后如下:
public class ThreadLocalDemo { private static int data = 0; private static Map<Thread,Integer> maps = new HashMap<Thread,Integer>(); public static void main(String[] args) { for(int i=0;i<4;i++){ new Thread(new Runnable() { @Override public void run() { data = new Random().nextInt(); System.out.println(Thread.currentThread().getName()+"has put data:"+data); maps.put(Thread.currentThread(),data); new A().get(); new B().get(); } }){}.start(); } } static class A{ public void get(){ int data = maps.get(Thread.currentThread()); System.out.println("A from"+Thread.currentThread().getName()+"data="+data); } } static class B{ public void get(){ int data = maps.get(Thread.currentThread()); System.out.println("B from"+Thread.currentThread().getName()+"data="+data); } } }
发现这个方案也是有问题的,问题出在哪呢?和之前分析的到底一样,哪现在怎么改呢?此刻无限的沉思之中,怎么办?还有什么办法呢?其实只要解决一个问题 就可以把所有的问题解决掉,哪就是变量data属于每个线程自己的属性,这个时候就是考察你基本功好不好的关键时刻了,其实只要把data变量不要做成类变量就可以了,
int data = new Random().nextInt();
好了问题解决了,现在改用java给我们提供好的ThreadLocal类
public class ThreadLocalDemo { private static int data = 0; static ThreadLocal<Integer> local = new ThreadLocal<Integer>(); public static void main(String[] args) { for(int i=0;i<4;i++){ new Thread(new Runnable() { @Override public void run() { int data = new Random().nextInt(); System.out.println(Thread.currentThread().getName()+"has put data:"+data); local.set(data); new A().get(); new B().get(); } }){}.start(); } } static class A{ public void get(){ data = local.get(); System.out.println("A from"+Thread.currentThread().getName()+"data="+data); } } static class B{ public void get(){ data = local.get(); System.out.println("B from"+Thread.currentThread().getName()+"data="+data); } } }看看多么简单就那么几行代码搞定,这就是java语言的强大之处,什么事都给你封装好了,如果线程共享有很多个变量,这个时候怎么办,哪直接把这些变量封装到一个类中,因为ThreadLcoal类可以保存任意的值!
相关文章推荐
- 线程范围内共享变量使用ThreadLocal类详细方法
- 使用JDK提供的ThreadLocal实现线程范围的共享变量(类似于Map<Thread,Variable>)
- 线程范围内共享变量的概念与作用以及ThreadLocal类及应用修复bug
- (三) Java多线程详解之线程范围内共享变量及ThreadLocal类使用
- 多线程编程入门(8):线程范围内的共享变量之ThreadLocal
- ThreadLocal线程范围内的共享变量
- Java多线程编程之ThreadLocal线程范围内的共享变量
- 线程高级应用-心得3-线程范围内的共享变量以及应用场景及面试题案例分析
- ThreadLocal实现线程范围的共享变量 代码示例
- 线程内部共享变量(ThreadLocal类使用初步)
- ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围的共享变量
- (5)ThreadLocal类及应用技巧---- 线程范围内共享变量
- 黑马程序员--javaSE--ThreadLocal实现线程范围的共享变量
- Java线程总结(四):ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围内共享变量和对象
- ThreadLocal实现线程范围的共享变量
- ThreadLocal实现线程范围的共享变量