-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathNote
82 lines (46 loc) · 3.18 KB
/
Note
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#2018-7-31
1、java.util.concurrent包中的队列
BlockingQueue接口 阻塞队列
ArrayBlockingQueue类 基于数组的BlockingQueue
LinkedBlockingQueue类 基于链表的BlockingQueue
PriorityBlockingQueue类 带有优先级的BlockingQueue
DelayQueue类 一定时间之后才可以take的BlockingQueue
SynchronousQueue类 直接传递的BlockingQueue
ConcurrentLinkedQueue类 元素个数没有最大限制的线程安全队列
volatile不会进行线程的互斥操作
关于重排序和可见性这两点,volatile的作用与synchronized的作用非常相似。但是volatile不进行线程的互斥处理。也就是说,访问volatile字段的线程不会进入等待队列。
访问volatile字段会产生性能开销
Java规范无法确保对long和double的赋值操作的原子性。
java.util.concurrent.atomic包 AtomicInteger AtomicLong等用于原子操作的类
java内存模型可以确保final字段在构造函数执行结束后可以正确地被看到
使用synchronized或者volatile来保护在多个线程之间的共享的字段
Java内存模型
重排序 :所谓重排序(Reorder),是指编译器和Java虚拟机通过改变程序的处理顺序来优化程序。
可见性
synchronized
volatile
final
Double-Checked Locking
与Javan内存模型交互时的指南
1、使用synchronized或volatile来保护在多个线程之间共享的字段
2、将常量字段设置为final
3、不要从构造函数中泄露this
####ThreadLocal#####
线程共享变量缓存如下:
Thread.ThreadLocalMap<ThreadLocal, Object>;
1、Thread: 当前线程,可以通过Thread.currentThread()获取。
2、ThreadLocal:我们的static ThreadLocal变量。
3、Object: 当前线程共享变量。
我们调用ThreadLocal.get方法时,实际上是从当前线程中获取ThreadLocalMap<ThreadLocal, Object>,然后根据当前ThreadLocal获取当前线程共享变量Object。
ThreadLocal.set,ThreadLocal.remove实际上是同样的道理。
这种存储结构的好处:
1、线程死去的时候,线程共享变量ThreadLocalMap则销毁。
2、ThreadLocalMap<ThreadLocal,Object>键值对数量为ThreadLocal的数量,一般来说ThreadLocal数量很少,
相比在ThreadLocal中用Map<Thread, Object>键值对存储线程共享变量(Thread数量一般来说比ThreadLocal数量多),性能提高很多。
关于ThreadLocalMap<ThreadLocal, Object>弱引用问题:
当线程没有结束,但是ThreadLocal已经被回收,则可能导致线程中存在ThreadLocalMap<null, Object>的键值对,造成内存泄露。
(ThreadLocal被回收,ThreadLocal关联的线程共享变量还存在)。
虽然ThreadLocal的get,set方法可以清除ThreadLocalMap中key为null的value,但是get,set方法在内存泄露后并不会必然调用,所以为了防止此类情况的出现,我们有两种手段。
1、使用完线程共享变量后,显示调用ThreadLocalMap.remove方法清除线程共享变量;
2、JDK建议ThreadLocal定义为private static,这样ThreadLocal的弱引用问题则不存在了。
####ThreadLocal#####