实例讲解Java并发编程之ThreadLocal类
程序员文章站
2024-03-31 18:37:22
threadlocal类可以理解为threadlocalvariable(线程局部变量),提供了get与set等访问接口或方法,这些方法为每个使用该变量的线程都存有一份独立...
threadlocal类可以理解为threadlocalvariable(线程局部变量),提供了get与set等访问接口或方法,这些方法为每个使用该变量的线程都存有一份独立的副本,因此get总是返回当前执行线程在调用set时设置的最新值。可以将threadlocal<t>视为 包含了map<thread,t>对象,保存了特定于该线程的值。
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而threadlocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
模拟threadlocal
复制代码 代码如下:
import java.util.collections;
import java.util.hashmap;
import java.util.map;
public class simplethreadlocal<t> {
private map<thread, t> valuemap = collections
.synchronizedmap(new hashmap<thread, t>());
public void set(t newvalue) {
valuemap.put(thread.currentthread(), newvalue); // ①键为线程对象,值为本线程的变量副本
}
public t get() {
thread currentthread = thread.currentthread();
t o = valuemap.get(currentthread); // ②返回本线程对应的变量
if (o == null && !valuemap.containskey(currentthread)) { // ③如果在map中不存在,放到map中保存起来。
o = initialvalue();
valuemap.put(currentthread, o);
}
return o;
}
public void remove() {
valuemap.remove(thread.currentthread());
}
protected t initialvalue() {
return null;
}
}
实用threadlocal
复制代码 代码如下:
class count {
private simplethreadlocal<integer> count = new simplethreadlocal<integer>() {
@override
protected integer initialvalue() {
return 0;
}
};
public integer increase() {
count.set(count.get() + 1);
return count.get();
}
}
class testthread implements runnable {
private count count;
public testthread(count count) {
this.count = count;
}
@override
public void run() {
// todo auto-generated method stub
for (int i = 1; i <= 3; i++) {
system.out.println(thread.currentthread().getname() + "\t" + i
+ "th\t" + count.increase());
}
}
}
public class testthreadlocal {
public static void main(string[] args) {
count count = new count();
thread t1 = new thread(new testthread(count));
thread t2 = new thread(new testthread(count));
thread t3 = new thread(new testthread(count));
thread t4 = new thread(new testthread(count));
t1.start();
t2.start();
t3.start();
t4.start();
}
}
输出
复制代码 代码如下:
thread-0 1th 1
thread-0 2th 2
thread-0 3th 3
thread-3 1th 1
thread-1 1th 1
thread-1 2th 2
thread-2 1th 1
thread-1 3th 3
thread-3 2th 2
thread-3 3th 3
thread-2 2th 2
thread-2 3th 3