线程范围内的环境变量---ThreadLocal

package cn.itcast.heima2;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class ThreadScopeShareData {

	private static int data = 0;
	private static 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(){
				@Override
				public void run() {
					int data = new Random().nextInt();
					System.out.println(Thread.currentThread().getName() 
							+ " has put data :" + data);
					threadData.put(Thread.currentThread(), data);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}
	
	static class A{
		public void get(){
			int data = threadData.get(Thread.currentThread());
			System.out.println("A from " + Thread.currentThread().getName() 
					+ " get data :" + data);
		}
	}
	
	static class B{
		public void get(){
			int data = threadData.get(Thread.currentThread());			
			System.out.println("B from " + Thread.currentThread().getName() 
					+ " get data :" + data);
		}		
	}
}

  从上面代码可以看出,这是模拟ThreadLocal的写法,其实ThreadLocal的功能就是一个以当前线程名为key的Map的存储结构。

  再对上面代码进行优化,可得到这样:

package cn.itcast.heima2;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class ThreadScopeShareData {

	private static int data = 0;
	private static ThreadLocal<Integer> threadData = 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();
					System.out.println(Thread.currentThread().getName()
							+ " has put data :" + data);
					threadData.set(data);
					new A().get();
					new B().get();
				}
			}).start();
		}
	}

	static class A{
		public void get(){
			int data = threadData.get();
			System.out.println("A from " + Thread.currentThread().getName()
					+ " get data :" + data);
		}
	}

	static class B{
		public void get(){
			int data = threadData.get();
			System.out.println("B from " + Thread.currentThread().getName()
					+ " get data :" + data);
		}
	}
}

  由于上面A,B两个类都属于内部静态类,所以他们可以共享变量 threadData,如果是写到外面,那么ThreadLocal<Integer>就要通过参数进行传递,如下:

package cn.itcast.heima2;

import java.util.HashMap;
import java.util.Map;
import java.util.Random;

public class ThreadScopeShareData {

	private static int data = 0;
	private static ThreadLocal<Integer> threadData = 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();
					System.out.println(Thread.currentThread().getName()
							+ " has put data :" + data);
					threadData.set(data);
					new A().get(threadData);
					new B().get(threadData);
				}
			}).start();
		}
	}


}

 class A{
	public void get(ThreadLocal<Integer> threadData){
		int data = threadData.get();
		System.out.println("A from " + Thread.currentThread().getName()
				+ " get data :" + data);
	}
}

 class B{
	public void get(ThreadLocal<Integer> threadData){
		int data = threadData.get();
		System.out.println("B from " + Thread.currentThread().getName()
				+ " get data :" + data);
	}
}

  

 与之对应的是关键字volatile,是线程之间共享的内容。

volatile关键字的两层语义

  一旦一个共享变量(类的成员变量、类的静态成员变量)被volatile修饰之后,那么就具备了两层语义:

  1)保证了不同线程对这个变量进行操作时的可见性,即一个线程修改了某个变量的值,这新值对其他线程来说是立即可见的。

  2)禁止进行指令重排序。

posted on 2020-06-04 15:36  芝麻开花——节节高  阅读(406)  评论(0编辑  收藏  举报

导航