- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章深入理解ThreadLocal工作原理及使用示例由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
简介:本文已一个简要的代码示例介绍threadlocal类的基本使用方式,在此基础上结合图片阐述它的内部工作原理.
早在jdk1.2的版本中就提供java.lang.threadlocal,threadlocal为解决多线程程序的并发问题提供了一种新的思路。使用这个工具类可以很简洁地编写出优美的多线程程序.
当使用threadlocal维护变量时,threadlocal为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本.
从线程的角度看,目标变量就象是线程的本地变量,这也是类名中“local”所要表达的意思.
所以,在java中编写线程局部变量的代码相对来说要笨拙一些,因此造成线程局部变量没有在java开发者中得到很好的普及.
1. threadlocal<t> 简介和使用示例 。
threadlocal只有一个无参的构造方法 。
public threadlocal() 。
threadlocal的相关方法 。
public t get() public void set(t value) public void remove() protected t initialvalue() 。
initialvalue方法的访问修饰符是protected,该方法为第一次调用get方法提供一个初始值。默认情况下,第一次调用get方法返回值null。在使用时,我们一般会复写threadlocal的initialvalue方法,使第一次调用get方法时返回一个我们设定的初始值.
下面是一个threadlocal的一个简单使用示例 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
package
javalearning;
import
java.util.random;
import
java.util.concurrent.executorservice;
import
java.util.concurrent.executors;
import
java.util.concurrent.semaphore;
public
class
threadlocaldemo {
/*定义了1个threadlocal<integer>对象,
*并复写它的initialvalue方法,初始值是3*/
private threadlocal<integer> tla = new threadlocal<integer>(){
protected integer initialvalue(){
return 3;
}
}
;
/*
private threadlocal<integer> tlb = new threadlocal<integer>(){
protected integer initialvalue(){
return 5;
}
};
*/
/*设置一个信号量,许可数为1,让三个线程顺序执行*/
semaphore semaphore = new semaphore(1);
private random rnd = new random();
/*worker定义为内部类实现了runnable接口,tla定义在外部类中,
每个线程中调用这个对象的get方法,再调用一个set方法设置一个随机值*/
public class worker implements runnable{
@override
public void run(){
try {
thread.sleep(rnd.nextint(1000));
/*随机延时1s以内的时间*/
semaphore.acquire();
/*获取许可*/
}
catch (interruptedexception e) {
e.printstacktrace();
}
int vala = tla.get();
system.out.println(thread.currentthread().getname() +" tla initial val : "+ vala);
vala = rnd.nextint();
tla.set(vala);
system.out.println(thread.currentthread().getname() +" tla new val: "+ vala);
/*
int valb = tlb.get();
system.out.println(thread.currentthread().getname() +" tlb initial val : "+ valb);
valb = rnd.nextint();
tla.set(valb);
system.out.println(thread.currentthread().getname() +" tlb 2 new val: "+ valb);
*/
semaphore.release();
/*在线程池中,当线程退出之前一定要记得调用remove方法,因为在线程池中的线程对象是循环使用的*/
tla.remove();
/*tlb.remove();*/
}
}
/*创建三个线程,每个线程都会对threadlocal对象tla进行操作*/
public
static
void
main(string[] args){
executorservice es = executors.newfixedthreadpool(
3
);
threadlocaldemo tld =
new
threadlocaldemo();
es.execute(tld.
new
worker());
es.execute(tld.
new
worker());
es.execute(tld.
new
worker());
es.shutdown();
}
}
|
运行结果 。
1
2
3
4
5
6
|
pool-
1
-thread-
1
tla initial val :
3
pool-
1
-thread-
1
tla
new
val: -
1288455998
pool-
1
-thread-
3
tla initial val :
3
pool-
1
-thread-
3
tla
new
val:
112537197
pool-
1
-thread-
2
tla initial val :
3
pool-
1
-thread-
2
tla
new
val: -
12271334
|
从运行结果可以看出,每个线程第一次调用theadlocal对象的get方法时都得到初始值3,注意我们上面的代码是让三个线程顺序执行,显然从运行结果看,pool-1-thread-1线程结束后设置的新值,对pool-1-thread-3线程是没有影响的,pool-1-thread-3线程完成后设置的新值对pool-1-thread-2线程也没有影响。这就仿佛把threadlocal对象当做每个线程内部的对象一样,但实际上tla对象是个外部类对象,内部类worker访问到的是同一个tla对象,也就是说是被各个线程共享的。这是如何做到的呢?我们现在就来看看threadlocal对象的内部原理.
2.threadlocal<t>的原理 。
首先,在thread类中定义了一个threadlocals,它是threadlocal.threadlocalmap对象的引用,默认值是null。threadlocal.threadlocalmap对象表示了一个以开放地址形式的散列表。当我们在线程的run方法中第一次调用threadlocal对象的get方法时,会为当前线程创建一个threadlocalmap对象。也就是每个线程都各自有一张独立的散列表,以threadlocal对象作为散列表的key,set方法中的值作为value(第一次调用get方法时,以initialvalue方法的返回值作为value)。显然我们可以定义多个threadlocal对象,而我们一般将threadlocal对象定义为static类型或者外部类中。上面所表达的意思就是,相同的key在不同的散列表中的值必然是独立的,每个线程都是在各自的散列表中执行操作.
theadlocal中的get源代码 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
public
t get() {
thread t = thread.currentthread();
threadlocalmap map = getmap(t);
if
(map !=
null
) {
threadlocalmap.entry e = map.getentry(
this
);
//这里的this是指当前的threadlocal对象
if
(e !=
null
) {
@suppresswarnings
(
"unchecked"
)
t result = (t)e.value;
return
result;
}
}
return
setinitialvalue();
}
|
总结 。
以上就是本文关于深入理解threadlocal工作原理及使用示例的全部内容,希望对大家有所帮助。如有不足之处,欢迎留言指出.
原文链接:http://www.cnblogs.com/nullzx/p/7553538.html 。
最后此篇关于深入理解ThreadLocal工作原理及使用示例的文章就讲到这里了,如果你想了解更多关于深入理解ThreadLocal工作原理及使用示例的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我一直在读这个article关于 Tomcat 中的 ThreadLocal 泄漏。第一个示例包含以下代码: public class MyCounter { private int
天真地,我希望 ThreadLocal 是 Thread 到值类型的某种 WeakHashMap。所以当我了解到一个 ThreadLocal 的值实际上是 saved in a map in the
一 简单例子 1 代码 package concurrent.threadlocal; /** * ThreadLocal测试 * * @author cakin */ public class T
并发编程-ThreadLocal 说在前面的话 今天的文章很短,但是很经典,值得你仔细阅读每一个文字… 正如我开篇所说,我们要整理一些java并发编程的学习文档,这一篇就是第七篇:ThreadLoca
最近接了一个新需求,业务场景上需要在原有基础上新增2个字段,接口新增参数意味着很多类和方法的逻辑都需要改变,需要先判断是否属于该业务场景,再做对应的逻辑。原本的打算是在入口处新增变量,在操作数据的时
前言 ThreadLocal为变量在每个线程中都创建了一个副本,所以每个线程可以访问自己内部的副本变量,不同线程之间不会互相干扰。本文会基于实际场景介绍ThreadLocal如何使用以及内部实现机
来源:blog.csdn.net/mycs2012/article/details/90898128 1、FastThreadLocal的引入背景和原理简介 2、实现源码分析 2.1、Unpadded
来源:blog.csdn.net/mycs2012/article/details/90898128 1、FastThreadLocal的引入背景和原理简介 2、实现源码分析 2.1、Unpadded
.Net 4. ThreadLocal<> 实现 IDisposable。但似乎调用 Dispose() 实际上并没有释放对所持有的线程本地对象的引用。 这段代码重现了这个问题: using Syst
在类(class)ReentrantReadWriteLock以下是奇怪的评论: transient ThreadLocalHoldCounter readHolds; Sync() { re
如果我们有一个 ThreadLocal 属性(每个线程都有其唯一的属性),那么哪个是正确的(我们不想使用自动 setter/getter): A) private ThreadLocal _someP
我正在浏览 ThreadLocal类文档,想知道它可以在什么场景下使用。 首先我认为它可以用于那些我们有第三方/遗留类并且我们想要处理同步问题的场景。然后我查看了 ThreadLocal 的其他示例,
我最近读了一篇关于 Equation Group's Sophisticated Hacking 的文章确凿的证据是一个常量,也出现在 JDK 8 源代码中,例如ThreadLocal.java HA
我的基于 ThreadLocal 的类遇到问题。任何帮助,将不胜感激。这是一个带有简单列表的基类: public class ThreadLocalTest { protected static fi
使用ThreadLocal类编程时,字段应该声明为final吗?如果编写类似 private ThreadLocal threadLocal 的代码稍后在构造函数中初始化它,因为变量 threadLo
我有以下类(class) 这个类用来保存我所有的ThreadLocal数据成员 public class ThreadLocalManager { public static final Th
在一次工作 session 上。我听说Thread Local绝对是一种反模式,因为新的应用程序服务器使用称为新IO的新线程技术。事实上,他们告诉我ThreadLocal的问题是一个完整的线程必须等待
ThreadLocal 是否会自动清除为已完成的线程创建的值? 最佳答案 是的,这些变量可用于垃圾收集,但前提是没有其他对这些值的引用(由其他线程持有)。但是当你说一个线程完成时,它不应该像一个线程池
我意识到 ThreadLocal 已被多次访问,尤其是 SimpleDateFormat 示例。 但似乎即使将 SDF 设置为“ThreadLocal”,我们仍然为每个线程创建一个 SDF() 实例,
在 JSR 315 中添加了对 servlet 和过滤器的异步支持。在这样的过滤器中创建的 ThreadLocal 线程安全吗? ResourceFilter com.app.fil
我是一名优秀的程序员,十分优秀!