首页 线程范围内的共享变量

线程范围内的共享变量

举报
开通vip

线程范围内的共享变量线程范围内的共享变量,每个线程只能访问他自己的,不能访问别的线程的。 下面请看一个不安全的例子,这个例子中的data数据有安全问题,可以测试一下 view plain import java.util.Random; public class ThreadScopeShareData { public static int data; /** * @param args */ public static void main(String[] arg...

线程范围内的共享变量
线程范围内的共享变量,每个线程只能访问他自己的,不能访问别的线程的。 下面请看一个不安全的例子,这个例子中的data数据有安全问题,可以测试一下 view plain import java.util.Random; public class ThreadScopeShareData { public static int data; /** * @param args */ public static void main(String[] args) { for(int i=0;i<2;i++){ new Thread(new Runnable(){ @Override public void run() { data = new Random().nextInt(); new ThreadA().getData(); new ThreadB().getData(); } }).start(); } } static class ThreadA{ public void getData(){ System.out.println("ThreadA -- " + Thread.currentThread().getName()+"-data=" + data); } } static class ThreadB{ public void getData(){ System.out.println("ThreadB -- " + Thread.currentThread().getName()+"-data=" + data); } } } 对与上述程序如何修改呢,就是实现一个类似于ThreadLocal的类一种实现,就是创建一个Map集合,键是线程自己,数据是data,取数据的时候就不会取错了。 代码如下: view plain import java.util.HashMap; import java.util.Map; import java.util.Random; public class ThreadScopeShareData { public static int data; public static Map dataMap = new HashMap(); /** * @param args */ public static void main(String[] args) { for(int i=0;i<2;i++){ new Thread(new Runnable(){ @Override public void run() { data = new Random().nextInt(); dataMap.put(Thread.currentThread(), data); new ThreadA().getData(); new ThreadB().getData(); } }).start(); } } static class ThreadA{ public void getData(){ System.out.println("ThreadA -- " + Thread.currentThread().getName()+"-data=" + dataMap.get(Thread.currentThread())); } } static class ThreadB{ public void getData(){ System.out.println("ThreadB -- " + Thread.currentThread().getName()+"-data=" + dataMap.get(Thread.currentThread())); } } } 这种实现方式类似于一些大型框架的底层实现。可以好好的看一下。 ThreadLocal 其实 ThreadLocal 并非是一个线程的本地实现,它并不是一个 Thread ,而是 Thread Local Variable(线程局部变量),它的功能就是为每一个使用该变量的线程 提供一个变量值的副本,每一个线程都可以独立地改变自己的副本而不影响其它线程。从线程的角度来看,就好像没一个线程都完全拥有该变量。 ThreadLocal 与其它线程同步机制的区别 ThreadLocal 与其它同步机制都是为了解决多线程中对同一变量的访问冲突,在普通的同步机制中,是通过对象加锁来实现多个线程对同一变量的安全访问,这时该变量是多个线 程共享的,使用这种同步机制需要很细致的分析出某时是哪个线程在操作该变量。 ThreadLocal 是从另一个角度来解决多线程的并发访问,ThreadLocal 会为每一个线程管理一个和该线程绑定的变量副本,从而隔离了对歌线程的数据,每一个线程都拥有自己的变量副本,因此也没有必要对该变量同步了。 ThreadLocal 并不能代替其它同步机制,两者面向的方向不同。其它同步机制是为了同步多个线程对相同资源的并发访问,是为了对个线程之间进行通信的有效方式,而 ThreadLocal 是隔离多个线程的数据共享,从根本上就不存在多个线程的共享资源。所以,如果你需要进行多个线程之间的通信,则使用同步机制,如果需要隔离多个线程之间的 共享冲突,可以使用 ThreadLocal ,这将极大简化代码量,并且美观易读。 ThreadLocal 内部机制 在 ThreadLocal 中,有一个Map集合,其中线程的对象引用作为键(key),而值(value)存放的是你丢进去的对象。对于同一个线程返回的是同一个 value,不同的线程返回的是不同的 value。这是通过 ThreadLocal 的 set()、get() 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 实现的。在某一个线程结束前,应当清除存放在 ThreadLocal 中的对象,否则会导致服务器存放过多的垃圾。清除对象的方法是,在该线程下,调用 ThreadLocal 对象的 remove() 方法。 ThreadLocal 常见方法 void set(Object value) 设置当前线程的局部变量的值 Object get() 返回当前线程的局部变量的值 void remove() 将当前线程的局部变量的值删除,目的是为了减少内存占用。 当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。 protected Object intialValue 返回该线程的局部变量的初始值。该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用 get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。 举例说明 ThreadLocal 的使用方法 编写代码,实现5个线程对同一对象的访问,并且保证在一个线程内获取的对象是同一个对象。 view plain HYPERLINK "http://blog.csdn.net/driverking/article/details/6557513#"print HYPERLINK "http://blog.csdn.net/driverking/article/details/6557513#"? ·········10········20········30········40········50········60········70········80········90········100·······110·······120·······130·······140·······150 import java.util.Random; public class Demo { public static void main(String[] args) { final A a = new A(); final B b = new B(); for (int i = 0; i < 5; i++) { new Thread() { public void run() { MyThredLocal.getInstance().setIndex( new Random().nextInt(100)); a.getA(); b.getB(); }; }.start(); MyThredLocal.clear(); } } } class MyThredLocal { private MyThredLocal() { } public static ThreadLocal instanceContainer = new ThreadLocal(); private int index; public int getIndex() { return index; } public void setIndex(int index) { this.index = index; } public static MyThredLocal getInstance() { MyThredLocal instance = instanceContainer.get(); if (instance == null) { if (instance == null) { instance = new MyThredLocal(); instanceContainer.set(instance); } } return instance; } public static void clear() { instanceContainer.remove(); } } class A { public void getA() { MyThredLocal myThredLocal = MyThredLocal.getInstance(); System.out.println(Thread.currentThread().getName() + "A:" + myThredLocal.getIndex()); } } class B { public void getB() { MyThredLocal myThredLocal = MyThredLocal.getInstance(); System.out.println(Thread.currentThread().getName() + "B:" + myThredLocal.getIndex()); } } 运行结果为: Thread-0A:21 Thread-1A:44 Thread-4A:57 Thread-3A:55 Thread-2A:23 Thread-3B:55 Thread-4B:57 Thread-1B:44 Thread-0B:21 Thread-2B:23 由此反应出 ThreadLocal 保证了同一线程内的变量共享。
本文档为【线程范围内的共享变量】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_157843
暂无简介~
格式:doc
大小:122KB
软件:Word
页数:7
分类:互联网
上传时间:2012-02-10
浏览量:15