Java ThreadLocal

Java ThreadLocal

  • Java Thread Local
    • Creating a ThreadLocal
    • Accessing a ThreadLocal
    • Generic ThreadLocal
    • Initial ThreadLocal Value
    • Full ThreadLocal Example
    • Inheritable ThreadLocal

Java Thread Local

Java中的ThreadLocal类使您可以创建只能由同一线程读取和写入的变量。 因此,即使两个线程正在执行相同的代码,并且代码具有对ThreadLocal变量的引用,那么这两个线程也看不到彼此的ThreadLocal变量。

Creating a ThreadLocal

下面是一个代码示例,演示如何创建ThreadLocal变量:

private ThreadLocal myThreadLocal = new ThreadLocal();

如您所见,您实例化一个新的ThreadLocal对象。 这只需要每个线程完成一次。 即使不同的线程执行访问ThreadLococal的相同代码,每个线程也只能看到自己的ThreadLocal实例。 即使两个不同的线程在同一个ThreadLocal对象上设置不同的值,它们也看不到彼此的值。

Accessing a ThreadLocal

创建ThreadLocal后,您可以设置要存储在其中的值,如下所示:

myThreadLocal.set("A thread local value");

创建ThreadLocal后,您可以设置要存储在其中的值,如下所示:

String threadLocalValue = (String)myThreadLocal.get();

get()方法返回一个Object,set()方法将Object作为参数。

Generic ThreadLocal

您可以创建一个通用的ThreadLocal,这样就不必对get()返回的值进行类型转换。 这是一个通用的ThreadLocal示例:

private ThreadLocal<String> myThreadLocal = new ThreadLocal<String>();

现在,您只能在ThreadLocal实例中存储字符串。 此外,您不需要对从ThreadLocal获取的值进行类型转换:

myThreadLocal.set("Hello ThreadLocla");

String msg = myThreadLocal.get();

Initial ThreadLocal Value

由于在ThreadLocal对象上设置的值仅对设置值的线程可见,因此没有线程可以使用set()在ThreadLocal上设置初始值.

相反,您可以通过继承ThreadLocal并覆盖initialValue()方法来为ThreadLocal对象指定初始值。

private ThreadLocal myThreadLocal = new ThreadLocal<String>() {
	@Override
	protected String initialValue() {
		return "This is the initial value";
	}
};

现在,在调用set()之前调用get()时,所有线程都会看到相同的初始值。

Full ThreadLocal Example

这是一个完全可运行的Java ThreadLocal示例:

package concurrency;

public class ThreadLocalDemo {
	
	public static class MyRunnable implements Runnable {

		private ThreadLocal<Integer> threadLocal = new ThreadLocal<>();
		
		public void run() {
			
			threadLocal.set((int)(Math.random() * 100D));
			
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				
			}
			
			System.out.println(threadLocal.get());
		}
	}
	
	public static void main(String[] args) throws Exception {
		
		MyRunnable myRunnable = new MyRunnable();
		
		Thread thread1 = new Thread(myRunnable);
		Thread thread2 = new Thread(myRunnable);
		
		thread1.start();
		thread2.start();
		
		thread1.join();
		thread2.join();
		
		System.out.println(Thread.currentThread().getName());
	}
	
}

此示例创建一个MyRunnable实例,该实例将传递给两个不同的线程。 两个线程都执行run()方法,因此在ThreadLocal实例上设置不同的值。 如果对set()调用的访问已经同步,并且它不是ThreadLocal对象,则第二个线程将覆盖第一个线程设置的值。

Inheritable ThreadLocal

InheritableThreadLocal类是ThreadLocal的子类。 InheritableThreadLocal不是每个线程在ThreadLocal中都有自己的值,而是授予该线程创建的所有子线程访问权限。

翻译自: http://tutorials.jenkov.com/java-concurrency/threadlocal.html
原作者: Jakob Jenkov

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