Java ThreadLocal类

本文详细介绍了Java中的ThreadLocal类,解释了其如何为每个线程提供独立的变量副本,并通过示例代码展示了ThreadLocal的基本使用方法及其子类InheritableThreadLocal的特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近项目重构的时候,接触到了ThreadLocal这个类,才知道原来关于线程还有这么个东东,真是疏漏寡闻了。


ThreadLocal类是做什么用的呢?

网上Copy了一段英文的介绍:The ThreadLocal class in Java enables you to create variables that can only be read and written by the same thread. Thus, even if two threads are executing the same code, and the code has a reference to a ThreadLocal variable, then the two threads cannot see each other's ThreadLocal variables.


通俗点讲就是通过ThreadLocal类,可以为线程创建一些对象(变量)放在ThreadLocal对象中,之后只有同地线程可以从ThreadLocal对象中取回这些对象(变量),其它线程访问相同的ThreadLocal类只有获取自己保存的对象(变量)。

来看一个例子。

import java.util.concurrent.TimeUnit;

public class App {
	
	public static final ThreadLocal<String> threadId = new ThreadLocal<String>();

	public static void main(String[] args) {
		for (int i = 1; i<= 10; i++) {
			new TheThread("id" + i).start();
		}
	}

}

class TheThread extends Thread {
	
	private String id;
	
	TheThread(String id) {
		this.id = id;
	}

	@Override
	public void run() {
		App.threadId.set(id);
		
		try {
			TimeUnit.SECONDS.sleep(5);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		System.out.println( id.endsWith(App.threadId.get()) );
	}
	
}

App类初始化了唯一一个static final的ThreadLocal对象threadId,之后启动10个TheThread线程。每个线程在创建时把参数id保存到自己的私有成员id中,在执行的时候,把自己的id保存到唯一的hreadId对象t中,然后sleep5秒,目的是让所有的线程都访问过threadId后,再输出最后的System.out。结果大家应该猜到了吧,就是输出10行true。ThreadLocal的get()方法返回的结果要么是空,要么是当前线程自己先前存放的东西,别的线程无法获取,很容易理解,但是很有用的一个类。


如果一个线程在没有存值前就调用ThreadLocal.get()方法,返回值会是null。如果希望ThreadLocal在这种情况下返回一个默值,可以在初始化ThreadLocal时创建一个匿名内部类,覆盖initialValue()方法:

public static final ThreadLocal<String> threadId = new ThreadLocal<String>(){

		@Override
		protected String initialValue() {
			return "the default thing";
		}
		
	};

ThreadLocal还有一个子类InheritableThreadLocal,顾名思义就是子线程可以访问父线程存放到ThreadLocal中的对象(变量),来看个例子:

public class App {
	
	public static final ThreadLocal<String> threadLocal = new InheritableThreadLocal<String>();

	public static void main(String[] args) {
		threadLocal.set("idRoot");
		
		new Thread(){
			public void run() {
				threadLocal.set("first parent thread");
				
				new TheThread().start();
				new TheThread().start();
			}
		}.start();
		
		new Thread(){
			public void run() {
				threadLocal.set("second parent thread");
				
				new TheThread().start();
				new TheThread().start();
			}
		}.start();
		
	}

}

class TheThread extends Thread {
	
	@Override
	public void run() {
		System.out.println( App.threadLocal.get() );
	}
	
}

代码很简单,就不解释了,输出结果是两行first parent thread和两行second parent thread,但顺序会不一样。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值