摘要:1.线程范围内共享变量 1.1 前奏:使用一个Map来实现线程范围内共享变量 public class ThreadScopeShareData { static Map<Thread, Integer> dataMap = new HashMap
1.线程范围内共享变量
1.1 前奏:
使用一个Map来实现线程范围内共享变量
public class ThreadScopeShareData {
static Map<Thread, Integer> dataMap = new HashMap<Thread, 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(); // 获取一个随机整数
System.out.println(Thread.currentThread().getName()
+ " put data " + data);
dataMap.put(Thread.currentThread(), data);
new A().get();
new B().get();
}
}).start();
}
}
static class A {
public void get() {
System.out.println(Thread.currentThread().getName() + " get data "
+ dataMap.get(Thread.currentThread()));
}
}
static class B {
public void get() {
System.out.println(Thread.currentThread().getName() + "get data "
+ dataMap.get(Thread.currentThread()));
}
}
}1.2 ThreadLocal类实际上就是一种map
/**
* ThreadLocal 类 这里ThreadLocal存放一个变量,如果有多个变量, 可以先将多个变量封装为一个对象
*
* @author Administrator
*
*/
public class ThreadLocalTest {
static ThreadLocal<Integer> x = new ThreadLocal<>(); //
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(); // 获取一个随机整数
System.out.println(Thread.currentThread().getName()
+ " put data " + data);
x.set(data);
new A().get();
new B().get();
}
}).start();
}
}
static class A {
public void get() {
System.out.println(Thread.currentThread().getName() + " get data "
+ x.get());
}
}
static class B {
public void get() {
System.out.println(Thread.currentThread().getName() + "get data "
+ x.get());
}
}
}2.线程范围内共享多个变量,可以将多个变量封装为一个对象
/**
* ThreadLocal 类 这里ThreadLocal存放一个变量,如果有多个变量, 可以先将多个变量封装为一个对象
*
* @author Administrator
*
*/
public class ThreadLocalTest {
static ThreadLocal<Integer> x = new ThreadLocal<>(); //
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(); // 获取一个随机整数
System.out.println(Thread.currentThread().getName()
+ " put data " + data);
x.set(data);
MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();//获取与线程绑定的对象
myData.setName("name"+data);
myData.setAge(data);
System.out.println(Thread.currentThread().getName()
+ " put Object " + "name: "+myData.getName()+","+" age: "+myData.getAge());
new A().get();
new B().get();
}
}).start();
}
}
static class A {
public void get() {
System.out.println(Thread.currentThread().getName() + " get data "
+ x.get());
MyThreadScopeData instance = MyThreadScopeData.getThreadInstance(); //直接获取与该线程相关的对象
System.out.println(Thread.currentThread().getName() + " get Object "
+ "name: "+instance.getName()+","+" age: "+instance.getAge());
}
}
static class B {
public void get() {
System.out.println(Thread.currentThread().getName() + "get data "
+ x.get());
MyThreadScopeData instance = MyThreadScopeData.getThreadInstance(); //直接获取与该线程相关的对象
System.out.println(Thread.currentThread().getName() + " get Object "
+ "name: "+instance.getName()+","+" age: "+instance.getAge());
}
}
}
// 单例
class MyThreadScopeData { //类的实例是与线程相关的,那么类的设计就交由类自身完成,只要调用自然就是与线程有关的
private static ThreadLocal<MyThreadScopeData> map = new ThreadLocal<>();
private MyThreadScopeData() {
}
public static MyThreadScopeData getThreadInstance() { // 线程间是相互独立的,这里不需要考虑同步
MyThreadScopeData instance = map.get();
if (instance == null) {
instance = new MyThreadScopeData();
map.set(instance);
}
return instance;
}
private String name;
private Integer age;
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name
* the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the age
*/
public Integer getAge() {
return age;
}
/**
* @param age
* the age to set
*/
public void setAge(Integer age) {
this.age = age;
}
}打印结果
Thread-1 put data -723086824
Thread-0 put data 772514756
Thread-1 put Object name: name-723086824, age: -723086824
Thread-0 put Object name: name772514756, age: 772514756
Thread-0 get data 772514756
Thread-1 get data -723086824
Thread-0 get Object name: name772514756, age: 772514756
Thread-1 get Object name: name-723086824, age: -723086824
Thread-0get data 772514756
Thread-1get data -723086824
Thread-0 get Object name: name772514756, age: 772514756
Thread-1 get Object name: name-723086824, age: -723086824
类的实例是与线程相关的,那么类的设计就交由类自身完成,只要调用自然就是与线程有关的 strust2的主要思想就是这么设计的
参看JAVA API
ThreadLocal有一个 remove()方法
可以移除与该线程相关的变量
remove()
Removes the current thread's value for this thread-local variable.
补充:
虚拟机的对应类 Runtime ,中有一个方法 addShutdownHook(Thread hook)
addShutdownHook(Thread hook)
Registers a new virtual-machine shutdown hook.
例如可以写一个发送邮件的线程Thread,当虚拟机挂掉之前会调用传入的Thread,发送一封邮件。
线程中是不是也应该有这种机制,当一个线程挂掉之前可以执行一个之前注册好的事件,或者有一个监听器在监听线程的状态,从而进行回调
在获取到线程挂掉的通知,就可以把该线程相关的变量全部remove获取clear掉