线程中多模块共享数据

之前项目中经常会碰到线程共享数据的场景,简单总结下:

1、通常情况会用java.lang.ThreadLocal来实现线程范围的共享变量,线程内共享,线程外独立;

2、ThreadLocal的作用和目的:用于实现线程内的数据共享,即对于相同的程序代码,多个模块在同一个线程中运行时要共享一份数据,而在另外线程中运行时又共享另外一份数据。

应用场景:订单处理、银行转账;

3、demo

package cn.cloudBy.concurrent;

import java.util.Random;

/**
 * @description:different modules(different classes or methods) share data in one thread
 * @author: sunyan
 * @time: 2016年1月7日 上午9:30:33
 */
public class ThreadLocalTest {

	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();
					
					System.out.println(Thread.currentThread().getName()+ "put data:"+data);					
					MyThreadScopeData.getThreadInstance().setName("name" + data);
					
					MyThreadScopeData.getThreadInstance().setAge(data);
					
					new A().get();
					
					new B().get();
				}
			}).start();
		}
	}

	//moduleA
	static class A {
		
		public void get() {

			MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();
			System.out.println("A from " + Thread.currentThread().getName()
							+ " getMyData: " + myData.getName() + ","
							+ myData.getAge());
		}
	}

	//module B
	static class B {
		
		public void get() {

			MyThreadScopeData myData = MyThreadScopeData.getThreadInstance();
			System.out.println("B from " + Thread.currentThread().getName()
							+ " getMyData: " + myData.getName() + ","
							+ myData.getAge());
		}
	}
}

//data class
class MyThreadScopeData {
	
	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 MyThreadScopeData() {
	}

	private static ThreadLocal<MyThreadScopeData> map=new ThreadLocal<MyThreadScopeData>();

	public static MyThreadScopeData getThreadInstance() {

		MyThreadScopeData instance = map.get();

		if (instance == null) {

			instance = new MyThreadScopeData();

			map.set(instance);
		}
		return instance;
	}

}

 4、每个线程调用全局ThreadLocal对象的set方法,就相当于往其内部的map中增加一条记录,key分别是各自的线程,value是各自的set方法传进去的值。在线程结束时可以调用ThreadLocal.clear()方法,这样会更快释放内存,不调用也可以,因为线程结束后也可以自动释放相关的ThreadLocal变量(gc)。

你可能感兴趣的:(java,thread,threadLocal)