没有合适的资源?快使用搜索试试~ 我知道了~
Java资料-详解ThreadLocal
需积分: 0 0 下载量 140 浏览量
2023-06-16
09:34:37
上传
评论
收藏 231KB DOCX 举报
温馨提示
试读
23页
Java资料—详解ThreadLocal ;Java资料—详解ThreadLocal ;Java资料—详解ThreadLocal ;Java资料—详解ThreadLocal Java资料—详解ThreadLocal
资源推荐
资源详情
资源评论
Java 详解 ThreadLocal
ThreadLocal 主要用来提供线程局部变量,也就是变量只对当前线程可见,本文主要记录
一下对于 ThreadLocal 的理解。更多关于 Java 多线程的文章可以转到 这里。
线程局部变量
在多线程环境下,之所以会有并发问题,就是因为不同的线程会同时访问同一个共享变量,
例如下面的形式
public class MultiThreadDemo {
public static class Number {
private int value = 0;
public void increase() throws InterruptedException {
value = 10;
Thread.sleep(10);
System.out.println("increase value: " + value);
}
public void decrease() throws InterruptedException {
value = -10;
Thread.sleep(10);
System.out.println("decrease value: " + value);
}
}
public static void main(String[] args) throws InterruptedException {
final Number number = new Number();
Thread increaseThread = new Thread(new Runnable() {
@Override
public void run() {
try {
number.increase();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
Thread decreaseThread = new Thread(new Runnable() {
@Override
public void run() {
try {
number.decrease();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
increaseThread.start();
decreaseThread.start();
}
}
在上面的代码中,increase 线程和 decrease 线程会操作同一个 number 中 value,那
么输出的结果是不可预测的,因为当前线程修改变量之后但是还没输出的时候,变量有可能
被另外一个线程修改,下面是一种可能的情况:
increase value: 10decrease value: 10
一种解决方法是在 increase() 和 decrease() 方法上加上 synchronized 关键字进行同
步,这种做法其实是将 value 的 赋值 和 打印 包装成了一个原子操作,也就是说两者要么
同时进行,要不都不进行,中间不会有额外的操作。我们换个角度考虑问题,如果 value
只属于 increase 线程或者 decrease 线程,而不是被两个线程共享,那么也不会出现竞
争问题。一种比较常见的形式就是局部(local)变量(这里排除局部变量引用指向共享对
象的情况),如下所示:
public void increase() throws InterruptedException {
int value = 10;
Thread.sleep(10);
System.out.println("increase value: " + value);
}
不论 value 值如何改变,都不会影响到其他线程,因为在每次调用 increase 方法时,都
会创建一个 value 变量,该变量只对当前调用 increase 方法的线程可见。借助于这种思
想,我们可以对每个线程创建一个共享变量的副本,该副本只对当前线程可见(可以认为是
线程私有的变量),那么修改该副本变量时就不会影响到其他的线程。一个简单的思路是使
用 Map 存储每个变量的副本,将当前线程的 id 作为 key,副本变量作为 value 值,下
面是一个实现:
public class SimpleImpl {
public static class CustomThreadLocal {
private Map<Long, Integer> cacheMap = new HashMap<>();
private int defaultValue ;
public CustomThreadLocal(int value) {
defaultValue = value;
}
public Integer get() {
long id = Thread.currentThread().getId();
if (cacheMap.containsKey(id)) {
return cacheMap.get(id);
}
return defaultValue;
}
public void set(int value) {
long id = Thread.currentThread().getId();
cacheMap.put(id, value);
}
}
public static class Number {
private CustomThreadLocal value = new CustomThreadLocal(0);
public void increase() throws InterruptedException {
value.set(10);
Thread.sleep(10);
System.out.println("increase value: " + value.get());
}
public void decrease() throws InterruptedException {
value.set(-10);
Thread.sleep(10);
剩余22页未读,继续阅读
资源评论
Andy&lin
- 粉丝: 98
- 资源: 214
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功