JMM结构图:
JMM对同步的8种操作:
JMM的同步规则:
Countdownlatch介绍:
该类功能是可以阻塞线程,并在保证线程满足特定条件下,继续执行。如上图,Countdownlatch的cnt初始值是3,线程A调用await()方法,会阻塞,t1,t2,t3每次执行会将cnt-1,然后继续执行。直到cnt的值为0,则TA继续执行。
假设只有两个车道,同一地点,只能同时有两辆车通过,即并发就是两个。Semaphore优势是可以控制同一时间,线程的并发量。
原子性介绍:
先看看jdk中atomic包中的原子类:
看下图程序,拿atomicInteger
当调用count的incrementAndGet方法时候,内部调用下图所示方法:
Var1指的是count对象,
底层是compareAndSwapInt,该方法是个本地方法,从名字看出就是CAS操作。含义是拿到var2主内存的值和传入的var2值比较,如果相同,则执行相加操作。
atomicRefence的用法:
下图最后结果是4
AtomicIntegerFieldUpdater用法:
atomicBoolean里的cas,只能执行一次。含义是多个线程同时执行,只有一个线程执行该操作,其他线程不能执行。
比如下面代码结果一定是true,因为虽然有5000个线程同时运行,只有一个线程修改AtomicBoolean属性的变量
ABA问题:是指在某个线程CAS操作的时候,其他线程将A改成了B又改回了A,此时CAS发现A和底层的值A没有变。为了解决这个问题,
注:1.如果子类继承了父类,子类调用父类中synchronized方法,是没有同步效果的(synchronized不属于方法声明);、
2. synchronized,修饰非静态方法或者代码块时候,锁定的是调用的对象。一个类的两个不同对象调用该类的非静态同步方法,由于锁对象不同,是每个对象本身,所以是不起同步作用的。
如果修饰类或者静态方法或者静态代码块,锁定的就是这个类,此时,一个类的不同实例。两者很有区别。
原子对比:
下面介绍可见性:
Volatile可见性实现的方式(注意:volatile没有原子性)
实现原理概括就是,读取一个变量的时候,会强迫从主内存中读取该变量,而写一个变量的时候会强迫从线程工作空间刷新到主内存。具体如下:
关于有序性:
指令重排序不会影响单线程,但是会影响多线程
JVM的happend-before原则:
如果两个操作的执行,不能从happens-before原则中推导出来,那么就不能保证他们的有序性,虚拟机可以随意的对他们进行重排序。
原文地址:https://www.cnblogs.com/chengwu1996/p/10591298.html