package zhu;
/*
* 要求:
* 利用Thread的局部变量类ThreadLocal 封装数据
* 然后再赋值数据 实现一个线程有多分相同的变量,而且各线程之间的变量值互不影响
* 官方应用场景:
* 在Java的多线程编程中,为保证多个线程对共享变量的安全访问,通常会使用synchronized来保证同一时刻只有一个线程对共享变量进行操作。
* 这种情况下可以将类变量放到ThreadLocal类型的对象中,使变量在每个线程中都有独立拷贝,
* 不会出现一个线程读取变量时而被另一个线程修改的现象。
*
* */
import java.util.Random;
public class ThreadLocalTest {
// 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();
//向ThreadLocal对象中放入数据 但是隐含了当前线程
MyThreadLocalData.getInstance().setName(""+data);
System.out.println(Thread.currentThread().getName()+" get data:"+data);
new A().getData();//这里获取当前线程共享的数据
new B().getData();
}
}
).start();
}
static class A{
void getData(){
System.out.println("A from"+Thread.currentThread().getName()
+",name:"+MyThreadLocalData.getInstance().getName());
}
}
static class B{
void getData(){
System.out.println("B from"+Thread.currentThread().getName()+",name:"+MyThreadLocalData.getInstance().getName());
}
}
}
/**
* ThreadLocal的原理
在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。比如下面的示例实现:
* @author nn
*
*/
class MyThreadLocalData{
private static MyThreadLocalData myThreadLocalData=null;
//单利模式 饿式
public static MyThreadLocalData getInstance(){
//先从存储数据工具类中取 是否存在数据 因为把线程独享数据封装到对象中
myThreadLocalData = map.get();//由于从“map”对象中取是否存在独享数据,所以不必加锁
if(myThreadLocalData==null){
myThreadLocalData = new MyThreadLocalData();
//新建数据对象 则存入数据工具中
map.set(myThreadLocalData);
}
return myThreadLocalData;
}
private static ThreadLocal<MyThreadLocalData> map = new ThreadLocal<>();//创建存储当前线程的数据
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
/*
* 要求:
* 利用Thread的局部变量类ThreadLocal 封装数据
* 然后再赋值数据 实现一个线程有多分相同的变量,而且各线程之间的变量值互不影响
* 官方应用场景:
* 在Java的多线程编程中,为保证多个线程对共享变量的安全访问,通常会使用synchronized来保证同一时刻只有一个线程对共享变量进行操作。
* 这种情况下可以将类变量放到ThreadLocal类型的对象中,使变量在每个线程中都有独立拷贝,
* 不会出现一个线程读取变量时而被另一个线程修改的现象。
*
* */
import java.util.Random;
public class ThreadLocalTest {
// 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();
//向ThreadLocal对象中放入数据 但是隐含了当前线程
MyThreadLocalData.getInstance().setName(""+data);
System.out.println(Thread.currentThread().getName()+" get data:"+data);
new A().getData();//这里获取当前线程共享的数据
new B().getData();
}
}
).start();
}
static class A{
void getData(){
System.out.println("A from"+Thread.currentThread().getName()
+",name:"+MyThreadLocalData.getInstance().getName());
}
}
static class B{
void getData(){
System.out.println("B from"+Thread.currentThread().getName()+",name:"+MyThreadLocalData.getInstance().getName());
}
}
}
/**
* ThreadLocal的原理
在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。比如下面的示例实现:
* @author nn
*
*/
class MyThreadLocalData{
private static MyThreadLocalData myThreadLocalData=null;
//单利模式 饿式
public static MyThreadLocalData getInstance(){
//先从存储数据工具类中取 是否存在数据 因为把线程独享数据封装到对象中
myThreadLocalData = map.get();//由于从“map”对象中取是否存在独享数据,所以不必加锁
if(myThreadLocalData==null){
myThreadLocalData = new MyThreadLocalData();
//新建数据对象 则存入数据工具中
map.set(myThreadLocalData);
}
return myThreadLocalData;
}
private static ThreadLocal<MyThreadLocalData> map = new ThreadLocal<>();//创建存储当前线程的数据
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}