CAS无锁机制
6.cas无锁机制:CAS:Compare and Swap,即比较再交换。
6.1 Java内存模型:JMM(Java Memory Model)
在内存模型当中定义了一个主内存,所有声明的实例变量都存在于主内存当中,主内存的数据会共享给所有线程,每一个线程有一块工作内存,工作内存当中主内存数据的副本
当更新数据时,会将工作内存中的数据同步到主内存当中
6.2 CAS无锁机制:本身无锁,采用乐观锁的思想,在数据操作时对比数据是否一致,如果一致代表之前没有线程操作该数据,那么就会更新数据,如果不一致代表有县城更新则重试
CAS当中包含三个参数CAS(V,E,N),V标识要更新的变量,E标识预期值,N标识新值
运行过程:
1.线程访问时,先会将主内存中的数据同步到线程的工作内存当中
2.假设线程A和线程B都有对数据进行更改,那么假如线程A先获取到执行权限
3.线程A先会对比工作内存当中的数据和主内存当中的数据是否一致,如果一致(V==E)则进行更新,不一致则刷新数据,重新循环判断
4.这时更新完毕后,线程B也要进行数据更新,主内存数据和工作内存数据做对比,如果一致则进行更新,不一致则将主内存数据重新更新到工作内存,然后循环再次对比两个内存中的数据
直到一致为止
CAS无锁机制存在一个问题
ABA问题,如果将原来A的值改为了B,然后又改回了A,虽然最终结果没有发生改变,但是在过程中是对该数据进行了修改操作
解决该问题:在Java中并发包下有一个原子类:AtomicStampedReference,在该类当中通过版本控制判断值到底是否被修改
解释:如果对值进行了更改则版本号+1,那么在CAS当中不仅仅对比变量的值,还要对比版本号,如果值和版本号都相等则代表没有被修改,如果有一方不相等代表进行过更改
那么就从主内存中重新刷新数据到工作内存然后循环对比,直到成功为止~
7.保证线程安全的三个方面:
1.原子性:保证同一时刻该资源只能有一个线程访问修改,其他线程阻塞等待,例如Atomic包,锁
2.可见性:一个线程对于主内存的数据操作对于其他线程是可见的
3.有序性:一个线程观察其他线程中指令执行顺序,由于指令重排序存在,观察结果一般杂乱无序
原子性: 互斥访问,Atomic包,CAS算法,Synchronized,Lock
6.1 Java内存模型:JMM(Java Memory Model)
在内存模型当中定义了一个主内存,所有声明的实例变量都存在于主内存当中,主内存的数据会共享给所有线程,每一个线程有一块工作内存,工作内存当中主内存数据的副本
当更新数据时,会将工作内存中的数据同步到主内存当中
6.2 CAS无锁机制:本身无锁,采用乐观锁的思想,在数据操作时对比数据是否一致,如果一致代表之前没有线程操作该数据,那么就会更新数据,如果不一致代表有县城更新则重试
CAS当中包含三个参数CAS(V,E,N),V标识要更新的变量,E标识预期值,N标识新值
运行过程:
1.线程访问时,先会将主内存中的数据同步到线程的工作内存当中
2.假设线程A和线程B都有对数据进行更改,那么假如线程A先获取到执行权限
3.线程A先会对比工作内存当中的数据和主内存当中的数据是否一致,如果一致(V==E)则进行更新,不一致则刷新数据,重新循环判断
4.这时更新完毕后,线程B也要进行数据更新,主内存数据和工作内存数据做对比,如果一致则进行更新,不一致则将主内存数据重新更新到工作内存,然后循环再次对比两个内存中的数据
直到一致为止
CAS无锁机制存在一个问题
ABA问题,如果将原来A的值改为了B,然后又改回了A,虽然最终结果没有发生改变,但是在过程中是对该数据进行了修改操作
解决该问题:在Java中并发包下有一个原子类:AtomicStampedReference,在该类当中通过版本控制判断值到底是否被修改
解释:如果对值进行了更改则版本号+1,那么在CAS当中不仅仅对比变量的值,还要对比版本号,如果值和版本号都相等则代表没有被修改,如果有一方不相等代表进行过更改
那么就从主内存中重新刷新数据到工作内存然后循环对比,直到成功为止~
7.保证线程安全的三个方面:
1.原子性:保证同一时刻该资源只能有一个线程访问修改,其他线程阻塞等待,例如Atomic包,锁
2.可见性:一个线程对于主内存的数据操作对于其他线程是可见的
3.有序性:一个线程观察其他线程中指令执行顺序,由于指令重排序存在,观察结果一般杂乱无序
原子性: 互斥访问,Atomic包,CAS算法,Synchronized,Lock
可见性:synchronized,volatile
顺序性:happends-before
8.原子类
public class AtomicTest {
//定义一个原子类对象
private AtomicInteger atomicInteger=new AtomicInteger();
public void getCount(){
//+1再返回
System.out.println(atomicInteger.incrementAndGet());
}
8.原子类
public class AtomicTest {
//定义一个原子类对象
private AtomicInteger atomicInteger=new AtomicInteger();
public void getCount(){
//+1再返回
System.out.println(atomicInteger.incrementAndGet());
}
public static void main(String[] args) {
AtomicTest test=new AtomicTest();
for (int i = 1; i <=2; i++) {
new Thread(()->{
for (int j = 1; j <=100; j++) {
test.getCount();
}
}).start();
}
}
}
8.AQS:全成AbstractQueueSynchronizer,抽象队列同步器,这个类在java.util.concurrent.locks包下
它是一个底层同步工具类,比如CountDownLatch,Sammphore,ReentrantLock,ReentrantReadWriteLock等等都是基于AQS
底层三个内容:
1.state(用于计数器)
2.线程标记(哪一个线程加的锁)
3.阻塞队列(用于存放阻塞线程)
AtomicTest test=new AtomicTest();
for (int i = 1; i <=2; i++) {
new Thread(()->{
for (int j = 1; j <=100; j++) {
test.getCount();
}
}).start();
}
}
}
8.AQS:全成AbstractQueueSynchronizer,抽象队列同步器,这个类在java.util.concurrent.locks包下
它是一个底层同步工具类,比如CountDownLatch,Sammphore,ReentrantLock,ReentrantReadWriteLock等等都是基于AQS
底层三个内容:
1.state(用于计数器)
2.线程标记(哪一个线程加的锁)
3.阻塞队列(用于存放阻塞线程)