ThreadLocalは深く理解しています

2937 ワード

JDK 1.2のバージョンではjavaが提供されています.lang.ThreadLocal,ThreadLocalはマルチスレッドプログラムの同時問題を解決するために新しい考え方を提供した.このツールクラスを使用すると、美しいマルチスレッドプログラムを簡潔に作成できます.ThreadLocalはThreadではなく、Threadのローカル変数です.
ThreadLocalクラスには、各スレッドの変数のコピーを格納するMapがあります.
例を見てみましょう
import java.util.Random;

/**
 * ThreadLocal 
 * 
 * @author chinoukin
 *
 */
public class ThreadLocalTest {

	private static ThreadLocal x = new ThreadLocal<>();

	public static void main(String[] args) {
		new Thread(new Runnable() {

			@Override
			public void run() {
				int data = new Random().nextInt();
				x.set(data);
				System.out.println(Thread.currentThread().getName() + " id:" + data);

				MyLocalData myLocalData = MyLocalData.getMyLocalDataInstance();
				myLocalData.setId(data);
				myLocalData.setName(" ");

				new TestA().get();
				new TestB().get();

			}

		}, " 1").start();

		new Thread(new Runnable() {

			@Override
			public void run() {
				int data = new Random().nextInt();
				x.set(data);
				System.out.println(Thread.currentThread().getName() + " id:" + data);

				MyLocalData myLocalData = MyLocalData.getMyLocalDataInstance();
				myLocalData.setId(data);
				myLocalData.setName(" ");

				new TestA().get();
				new TestB().get();
			}

		}, " 2").start();
	}

	static class TestA {
		public void get() {
			int data = x.get();
			MyLocalData myLocalData = MyLocalData.getMyLocalDataInstance();
			System.out.println("A " + Thread.currentThread().getName() + " id:" + data);
			System.out.println("A " + Thread.currentThread().getName() + " name:" + myLocalData.getName());
		}
	}

	static class TestB {
		public void get() {
			int data = x.get();
			MyLocalData myLocalData = MyLocalData.getMyLocalDataInstance();
			System.out.println("B " + Thread.currentThread().getName() + " id:" + data);
			System.out.println("B " + Thread.currentThread().getName() + " name:" + myLocalData.getName());
		}
	}
}

/**
 *  (ThreadLocal)  , 
 * 
 * @author chinoukin
 *
 */
class MyLocalData {
	private MyLocalData() {
	}

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

	public static MyLocalData getMyLocalDataInstance() {
		MyLocalData myLocalData = map.get();
		if (myLocalData == null) {
			myLocalData = new MyLocalData();
			map.set(myLocalData);
		}
		return myLocalData;
	}

	private int id;
	private String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

}

実行結果:
 1 id:569578798
 2 id:-185649376
A 1 id:569578798
A 2 id:-185649376
A 1 name: 
A 2 name: 
B 2 id:-185649376
B 2 name: 
B 1 id:569578798
B 1 name: 
実行結果によって、各スレッド自体のThreadLocal変数は独立であり、スレッド間相互補完干渉であることが分かった.