线程共享数据以及ThreadLocal类
来源:互联网 发布:sysgettempdir php 编辑:程序博客网 时间:2024/05/08 17:08
线程范围内共享变量的概念与作用
代码演示:
class ThreadScopeShareData
{
三个模块共享数据,主线程模块和AB模块
private static int data = 0; 准备共享的数据
存放各个线程对应的数据
private Map<Thread, Integer> threadData = new HashMap<Thread, Integer>();
public static void main(String[] args)
{ 创建两个线程
for (int i=0; i<2; i++)
{
new Thread(
new Runnable()
{
public void run()
{现在当前线程中修改一下数据,给出修改信息
data = new Random().nextInt();
SOP(Thread.currentThread().getName()+将数据改为+data);
将线程信息和对应数据存储起来
threadData.put(Thread.currentThread(), data);
使用两个不同的模块操作这个数据,看结果
new A().get();
new B().get();
}
}
).start();
}
}
static class A
{
public void get()
{
data = threadData.get(Thread.currentThread());
SOP(A+Thread.currentThread().getName()+拿到的数据+data);
}
}
static class B
{
public void get()
{
data = threadData.get(Thread.currentThread());
SOP(B+Thread.currentThread().getName()+拿到的数据+data);
}
}
}
结果并没与实现线程间的数据同步,两个线程使用的是同一个线程的数据。要解决这个问题,可以将每个线程用到的数据与对应的线程号存放到一个map集合中,使用数据时从这个集合中根据线程号获取对应线程的数据。代码实现:上面红色部分
程序中存在的问题:获取的数据与设置的数据不同步
Thread-1共享数据设置为:-997057737
Thread-1--A 模块数据:-997057737
Thread-0共享数据设置为:11858818
Thread-0--A 模块数据:11858818
Thread-0--B 模块数据:-997057737
Thread-1--B 模块数据:-997057737
最好将Runnable中设置数据的方法也写在对应的模块中,与获取数据模块互斥,以保证数据同步
. ThreadLocal类及应用技巧
多个模块在同一个线程中运行时要共享同一份数据,实现线程范围内的数据共享可以用上一节中所用的方法。
JDK1.5提供了ThreadLocal类来方便实现线程范围内的数据共享,它的作用就相当于上一节中的Map。
每个线程调用全局ThreadLocal对象的set方法,就相当于往其内部的map集合中增加一条记录,key就是各自的线程,value就是各自的set方法传进去的值。
在线程结束时可以调用ThreadLocal.clear()方法用来更快释放内存,也可以不调用,因为线程结束后也可以自动释放相关的ThreadLocal变量。
一个ThreadLocal对象只能记录一个线程内部的一个共享变量,需要记录多个共享数据,可以创建多个ThreadLocal对象,或者将这些数据进行封装,将封装后的数据对象存入ThreadLocal对象中。
将数据对象封装成单例,同时提供线程范围内的共享数据的设置和获取方法,提供已经封装好了的线程范围内的对象实例,使用时只需获取实例对象即可实现数据的线程范围内的共享,因为该对象已经是当前线程范围内的对象了。下边给出张老师的优雅代码:
package cn.itheima;
import java.util.Random;
public class ThreadLocalShareDataDemo
{ /**06. ThreadLocal类及应用技巧
* 将线程范围内共享数据进行封装,封装到一个单独的数据类中,提供设置获取方法
* 将该类单例化,提供获取实例对象的方法,获取到的实例对象是已经封装好的当前线程范围内的对象
*/
public static void main(String[] args)
{
for (int i=0; i<2; i++)
{
new Thread(
new Runnable()
{
public void run()
{
int data = new Random().nextInt(889);
System.out.println(Thread.currentThread().getName()+"产生数据:"+data);
MyData myData = MyData.getInstance();
myData.setAge(data);
myData.setName("Name:"+data);
new A().get();
new B().get();
}
}).start();
}
}
static class A
{ //可以直接使用获取到的线程范围内的对象实例调用相应方法
String name = MyData.getInstance().getName();
int age = MyData.getInstance().getAge();
public void get()
{
System.out.println(Thread.currentThread().getName()+"-- AA name:"+name+"...age:"+age);
}
}
static class B
{
//可以直接使用获取到的线程范围内的对象实例调用相应方法
String name = MyData.getInstance().getName();
int age = MyData.getInstance().getAge();
public void get()
{
System.out.println(Thread.currentThread().getName()+"-- BB name:"+name+"...age:"+age);
}
}
static class MyData
{
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;
}
//单例
private MyData() {};
//提供获取实例方法
public static MyData getInstance()
{
//从当前线程范围内数据集中获取实例对象
MyData instance = threadLocal.get();
if (instance==null)
{
instance = new MyData();
threadLocal.set(instance);
}
return instance;
}
//将实例对象存入当前线程范围内数据集中
static ThreadLocal<MyData> threadLocal = new ThreadLocal<MyData>();
}
}
0 0
- 线程共享数据以及ThreadLocal类
- 线程数据共享-ThreadLocal
- ThreadLocal类实现线程范围内数据共享
- ThreadLocal线程范围内共享数据
- ThreadLocal实现线程范围内的数据共享
- 线程范围内的共享数据 ThreadLocal
- ThreadLocal-------线程范围内的数据共享
- ThreadLocal 线程内的数据共享(线程间隔离)
- java线程:单例隐藏ThreadLocal实现线程数据共享
- Java线程(二):线程数据共享及ThreadLocal使用
- 线程范围内共享变量的概念与作用以及ThreadLocal类及应用修复bug
- android 线程范围内共享变量以及ThreadLocal的使用
- 线程管理以及线程间数据共享
- 同一个线程不同模块间的数据共享 ThreadLocal
- 黑马程序员-线程范围内的数据共享之ThreadLocal
- ThreadLocal与Synchronized(线程安全与数据共享)
- 多线程之线程范围内的数据共享ThreadLocal
- Java基础:多线程之线程范围内的数据共享ThreadLocal
- C语言和php语言现在哪个更给力吃香
- Java的三大特性
- 一个 电脑原始人 的独白
- Myeclipse快捷键
- Effective C++ 8,9
- 线程共享数据以及ThreadLocal类
- 隨3--文件壓縮成base64,解壓
- Selenium IDE 使用Export Feature改变脚本语言类型
- 导入外部JS
- KMP--模式匹配算法
- 加油站...
- java中的定时器Timer类简介
- java5中的线程池简介。
- 概率统计中方差的计算区别