标签:null 编译 valueof cas 变量 cti thread mis public
package com.ruyidd.auxiliary;
import java.util.concurrent.CountDownLatch;
/**
*/
public class CountDownLatchDemo {
public static void main(String[] args) throws InterruptedException {
CountDownLatch downLatch = new CountDownLatch(6);
for (int i = 0; i < 6; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" Start");
downLatch.countDown();//
}).start();
}
downLatch.await();
//想实现的目标:等待上面的6个线程执行完毕,再执行main线程的End
System.out.println(Thread.currentThread().getName()+" End");
}
}
package com.ruyidd.auxiliary;
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
/**
* @author: tianxc
* @date: 2020-03-09 21:51
* @desc:
*/
public class CyclicBarrierDemo {
public static void main(String[] args) {
CyclicBarrier cyclicBarrier = new CyclicBarrier(7,()->{
System.out.println("已经集齐七颗龙珠,召唤神龙!");
});
for (int i = 1; i <= 7; i++) {
new Thread(()->{
System.out.println(Thread.currentThread().getName()+" 获得一颗龙珠");
try {
cyclicBarrier.await();//阻塞线程
System.out.println(Thread.currentThread().getName()+" 线程阻塞了吗?");
} catch (InterruptedException e) {
e.printStackTrace();
} catch (BrokenBarrierException e) {
e.printStackTrace();
}
},String.valueOf(i)).start();
}
}
}
package com.ruyidd.auxiliary;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
/**
* @author: tianxc
* @date: 2020-03-09 22:03
* @desc:
*/
public class SemaphoreDemo {
public static void main(String[] args) {
//Semaphore 信号量,可以用来限流
//模拟三个车位
Semaphore semaphore = new Semaphore(3);
//模拟6个车
for (int i = 1; i <= 6; i++) {
new Thread(()->{
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName()+" 获得了车位");
TimeUnit.SECONDS.sleep(3);
System.out.println(Thread.currentThread().getName()+" 离开了车位");
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
semaphore.release();
}
},String.valueOf(i)).start();
}
}
}
JMM只是一个理论。
所有的线程是如何工作的?
package com.ruyidd.jmm;
import java.util.concurrent.TimeUnit;
/**
* 验证volatile的可见性
*/
public class Demo1 {
private volatile static int num = 0;
public static void main(String[] args) throws InterruptedException {
new Thread(()->{
while (num==0){
}
}).start();
TimeUnit.SECONDS.sleep(1);
num = 1;
System.out.println(num);
}
}
package com.ruyidd.jmm;
import java.util.concurrent.CountDownLatch;
/**
* @author: tianxc
* @date: 2020-03-09 22:28
* @desc:
*/
public class Demo2 {
//volatile不保证原子性验证
private volatile static int num = 0;
//synchronized
public static void add(){
num++;//不是一个原子性的操作
}
public static void main(String[] args) throws InterruptedException {
CountDownLatch downLatch = new CountDownLatch(20000);
//期望num的值最终是两万
for (int i = 1; i <= 20; i++) {
new Thread(()->{
for (int i1 = 0; i1 < 1000; i1++) {
add();
downLatch.countDown();
}
},String.valueOf(i)).start();
}
downLatch.await();
System.out.println(Thread.currentThread().getName()+" "+num);
}
}
如何不用锁解决该问题
package com.ruyidd.jmm;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author: tianxc
* @date: 2020-03-09 22:28
* @desc:
*/
public class Demo3 {
//原子类
private static AtomicInteger atomicInteger = new AtomicInteger();
public static void add(){
atomicInteger.getAndIncrement();//原子性操作
}
public static void main(String[] args) throws InterruptedException {
CountDownLatch downLatch = new CountDownLatch(20000);
//期望num的值最终是两万
for (int i = 1; i <= 20; i++) {
new Thread(()->{
for (int i1 = 0; i1 < 1000; i1++) {
add();
downLatch.countDown();
}
},String.valueOf(i)).start();
}
downLatch.await();
System.out.println(Thread.currentThread().getName()+" "+atomicInteger.get());
}
}
指令重排:写的程序不一定是按照程序的顺序执行的
源代码->编译器(优化重排)->指定并行重排->内存系统重排->最终执行。
int x,y,a,b = 0;
线程1 线程2
x = a; y = b;
b = 1; a = 2;
理想的结果: x=0 y = 0
指令重排:
线程1 线程2
b = 1; a = 2;
x = a; y = b;
重排后的结果: x=2 y = 1
指定重排小结:
volatile 可以禁止指令重排!
内存屏障(Memory Barrier):CPU的指令,有两个作用:
DCL 懒汉式:双检锁懒汉式
package com.ruyidd.single;
import java.lang.reflect.Constructor;
/**
* @author: tianxc
* @date: 2020-03-09 22:56
* @desc:
*/
public class LazyMan {
private static boolean aldkfakjdfaklsdjf = false;
private LazyMan(){
synchronized (LazyMan.class){
if (aldkfakjdfaklsdjf==false){
aldkfakjdfaklsdjf = true;
}else{
throw new RuntimeException("不要试图破坏单例模式");
}
}
}
//禁止指令重排
private volatile static LazyMan lazyMan;
public static LazyMan getInstace(){
if(lazyMan==null){
synchronized (LazyMan.class){
if(lazyMan==null){
//用volatile禁止指令操作
lazyMan = new LazyMan();
/**
* Java 创建一个对象
* 1.分配内存空间
* 2.执行构造方法,创建对象
* 3.将对象指向空间
*/
}
}
}
return lazyMan;
}
public static void main(String[] args) throws Exception {
Class<LazyMan> clazz = LazyMan.class;
Constructor<LazyMan> declaredConstructor = clazz.getDeclaredConstructor(null);
LazyMan lazyMan1 = declaredConstructor.newInstance();
LazyMan lazyMan2 = declaredConstructor.newInstance();
System.out.println(lazyMan1.hashCode());
System.out.println(lazyMan2.hashCode());
}
}
在jdk源码没有修改的前提下,枚举是单例模式最安全的
package com.ruyidd.single;
import java.lang.reflect.Constructor;
/**
* @author: tianxc
* @date: 2020-03-09 23:08
* @desc:
*/
public enum SingleEnum {
INSTANCE;
public SingleEnum getInstance(){
return INSTANCE;
}
}
class SingleEnumDemo{
public static void main(String[] args) throws Exception {
// Constructor<SingleEnum> declaredConstructor = SingleEnum.class.getDeclaredConstructor(null);
// Cannot reflectively create enum objects
// Exception in thread "main" java.lang.NoSuchMethodException: com.ruyidd.single.SingleEnum.<init>()
// SingleEnum singleEnum = declaredConstructor.newInstance();
// System.out.println(singleEnum);
Constructor<SingleEnum> declaredConstructor = SingleEnum.class.getDeclaredConstructor(String.class,int.class);
declaredConstructor.setAccessible(true);
//Exception in thread "main" java.lang.IllegalArgumentException: Cannot reflectively create enum objects
SingleEnum singleEnum = declaredConstructor.newInstance();
System.out.println(singleEnum);
}
}
package com.ruyidd.jmm;
import java.util.concurrent.atomic.AtomicInteger;
/**
* @author: tianxc
* @date: 2020-03-09 23:15
* @desc:
*/
public class Demo4 {
public static void main(String[] args) {
// AtomicInteger 默认为0
AtomicInteger atomicInteger = new AtomicInteger(5);
// compareAndSet cas 比较并交换
// public final boolean compareAndSet(int expect, int update)
// 如果这个值是期望的值,那么则更新为指定的值。
System.out.println(atomicInteger.compareAndSet(5,20));
System.out.println(atomicInteger.get());
System.out.println(atomicInteger.compareAndSet(5,20));
System.out.println(atomicInteger.get());
}
}
分析:java.util.concurrent.atomic.AtomicInteger#getAndIncrement()
//java.util.concurrent.atomic.AtomicInteger#getAndIncrement
//unsafe可以直接操作内存
public final int getAndIncrement() {
//valueOffset 当前这个对象的值的内存地址偏移值
return unsafe.getAndAddInt(this, valueOffset, 1);
}
//sun.misc.Unsafe#getAndAddInt
public final int getAndAddInt(Object var1, long var2, int var4) {
int var5;
do {
//var = 获得当前对象的内存地址中的值
var5 = this.getIntVolatile(var1, var2);
//compareAndSwapInt 比较并交换
//比较当前的值,var1对象的var2地址中的值是不是var5,如果是则更新为var5+1
} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));
return var5;
}
cas小结
自旋锁:
package com.ruyidd.lock;
import java.util.concurrent.atomic.AtomicReference;
/**
* @author: tianxc
* @date: 2020-03-09 23:37
* @desc:
*/
public class MyLock {
//锁线程
//AtomicReference 默认是null
//AtomicInteger 默认是0
AtomicReference<Thread> atomicReference = new AtomicReference<>();
public void lock(){
Thread thread = Thread.currentThread();
System.out.println(thread.getName()+"===>get lock");
//上锁自旋
while (!atomicReference.compareAndSet(null,thread)){
}
}
public void unlock(){
Thread thread = Thread.currentThread();
atomicReference.compareAndSet(thread,null);
System.out.println(thread.getName()+"===>unlock");
}
}
public static void main(String[] args) {
MyLock lock = new MyLock();
new Thread(()->{
lock.lock();
try {
TimeUnit.SECONDS.sleep(5);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
},"T1").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
lock.lock();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();
}
},"T2").start();
}
标签:null 编译 valueof cas 变量 cti thread mis public
原文地址:https://www.cnblogs.com/tianxc/p/12455116.html