2017年12月8日-线程理解
最近看了一些关于线程方面的文档,写一篇关于自己理解的内容。
可能内容比较乱,也比较浅显,欢迎客观指正。
语言:JAVA
在这个语言中,一些名词的翻译总是让人忍不住骂人。
synchronized:java关键字,锁标志。记住一点,谁在使用,不外乎当前对象或者所有的对象,别被绕晕。
synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:
1、修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
2、修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
3、修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
4、修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
注:以上复制。
Lock:java.util.concurrent.locks.Lock,为什么有了synchronized关键字,还需要这个类。肯定是synchronized关键字有某些地方不满足开发的需求,是什么呢?因为它无法中断一个正在等候获得锁的线程,也无法通过轮询得到锁,如果不想等下去,也就没法得到锁。
注:个人建议看看,https://www.ibm.com/developerworks/cn/java/j-jtp10264/index.html#artrelatedtopics。不保证100%正确,只能在我有限理解下,觉得写得有道理。
ReentrantLock:Lock实现类,重入锁。等的太无聊,可以先去做其他事情。
CountDownLatch:倒计数门闸锁。大腕最后出场。
CyclicBarrier:可重用栏栅。爬上9楼一起等着上10楼。
FutureTask:Future实现类。你先去忙,等会告诉我结果。
Semaphore:基于计数的信号量。多副本的资源访问控制;内部仍然使用锁来控制资源的同步访问。
这么多的类,是不是有点晕。都用到了java.util.concurrent.locks.AbstractQueuedSynchronizer(简称:AQS),AQS是基于First Input First Output(FIFO)队列的实现。推荐:https://www.cnblogs.com/xrq730/p/4979021.html。
从硬件层面来说,提高使用效率带来的问题:
Cache Coherence,缓存一致性。解决方案,处理器访问缓存协议:
MSI、MESI、MOSI、Synapse、Firefly、Dragon Protocol。
MESI(Modified Exclusive Shared Or Invalid),MESI协议中的状态,CPU中每个缓存行(caceh line)使用4种状态进行标记(使用额外的两位(bit)表示)。
1、M:被修改(Modified),该缓存行只被缓存在该CPU的缓存中,并且是被修改过的(dirty),即与主存中的数据不一致,该缓存行中的内存需要在未来的某个时间点(允许其它CPU读取请主存中相应内存之前)写回(write back)主存。当被写回主存之后,该缓存行的状态会变成独享(exclusive)状态。
2、E:独享的(Exclusive),该缓存行只被缓存在该CPU的缓存中,它是未被修改过的(clean),与主存中数据一致。该状态可以在任何时刻当有其它CPU读取该内存时变成共享状态(shared)。同样地,当CPU修改该缓存行中内容时,该状态可以变成Modified状态。
3、S:共享的(Shared),该状态意味着该缓存行可能被多个CPU缓存,并且各个缓存中的数据与主存数据一致(clean),当有一个CPU修改该缓存行中,其它CPU中该缓存行可以被作废(变成无效状态(Invalid))。
4、I:无效的(Invalid),该缓存是无效的(可能有其它CPU修改了该缓存行)。
从JAVA内存模型来说:
1、Atomicity,原子性。使用锁和CAS(Compare and Swap)
2、Visibility,可见性。volatile、synchronized、final
3、Ordering,有序性。volatile、synchronized、先行发生原则。