java锁的理解
来源:互联网 发布:淘宝类目转化率查询 编辑:程序博客网 时间:2024/06/09 14:51
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 原子操作:不可被打断的一些列操作,32位多处理器主要通过对总线和缓存加锁保证原子性。
* 首先要保证原子性,需要处理器对于数据的处理要保证原子性,当一个处理器读取内存中的数据时,对于其他处理器是内存地址不可访问,即对于该内存地址加锁。
* 1,总线锁:当一个处理器读取内存中的数据时,对于共享内存的总线加Lock指令,其他处理器被阻塞,但这样其他处理器不能访问其他共享内存的数据。
* 2, 缓存锁:频繁使用的数据会缓存在L1、L2、L3缓存中,缓存一致性会阻止同时修改两个处理器缓存的同一个内存数据。通过回写改变内存的方式,使得另一个处理器写失败。
* 有一部分情况不能使用缓存锁定:1 , 处理器不支持缓存锁定 。 2 , 数据不能加载进处理器缓存。
* 对于一些inter指令,Inter处理器提供了很多LOCK前缀的指令,通过在指令前面加LOCK指令,会对缓存加锁,保证其他处理器不能同时访问数据。
* java中可以通过锁和循环CAS的方式来实现原子操作,java current包中的类大多是通过CAS方式实现的,CAS是基于处理器CMPXCHG指令。
* 在java中除了偏向锁(锁的等级分为无锁、偏向锁、轻量级锁、重量级锁),其他锁的方式都是通过CAS方式实现的。
* AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行CAS操作,对于这个对象的操作的原子性。
* 原子操作会有ABA的问题,当CompareAndSet时,比较的变量会有A-B-A的过程,则为false。通过添加版本号,变为A1-B2-A3。
* CAS是通过循环操作比较的,无限循环会大量消耗cpu。CAS一次只能操作一个变量,现在通过atomicReference,可以原子改变一个对象状态。
* AQS是一种思想,线程安全的集合用到了AQS思想,锁的实现是通过CAS实现的。通过AQS实现ReetrantLock的lock和unlock的过程,具体的lock获取,unlock通过CAS实现的。
* AQS - abstractQueueSynchronized,通过队列的方式管理lock,lock的实现通过CAS具体实现的。
* @author pc
*
*/
public class AtomicTest {
public AtomicInteger atomicI = new AtomicInteger(0);// 使用CAS操作,保证原子性。
public int i = 0;
public void unSafe(){
i++;
}
public void safeCount(){
for(;;){
int i = atomicI.get();
boolean flag = atomicI.compareAndSet(i, ++i);
if (flag){
break;
}
}
}
public static void main(String[] args){
final AtomicTest test = new AtomicTest();
/**
* final 的作用保证在多线程中的不可变性,即可以在多线程中直接使用
* final 关键字提高了性能,java应用和JVM都会缓存final关键字的变量
*
*/
List<Thread> list = new ArrayList<Thread>();
for(int j = 0; j < 1000; j++){
Thread t = new Thread(new Runnable(){
public void run(){
test.unSafe();
test.safeCount();
}
});
list.add(t);
}
for(Thread thread : list){
thread.start();
}
System.out.println(test.i);// 不能保证原子性,在同一时刻可能有多个线程修改i这个变量。
System.out.println(test.atomicI.get());// 保证了原子性,输出1000,在同一时刻只有一个线程修改这个atomicInteger这个变量。
}
}
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 原子操作:不可被打断的一些列操作,32位多处理器主要通过对总线和缓存加锁保证原子性。
* 首先要保证原子性,需要处理器对于数据的处理要保证原子性,当一个处理器读取内存中的数据时,对于其他处理器是内存地址不可访问,即对于该内存地址加锁。
* 1,总线锁:当一个处理器读取内存中的数据时,对于共享内存的总线加Lock指令,其他处理器被阻塞,但这样其他处理器不能访问其他共享内存的数据。
* 2, 缓存锁:频繁使用的数据会缓存在L1、L2、L3缓存中,缓存一致性会阻止同时修改两个处理器缓存的同一个内存数据。通过回写改变内存的方式,使得另一个处理器写失败。
* 有一部分情况不能使用缓存锁定:1 , 处理器不支持缓存锁定 。 2 , 数据不能加载进处理器缓存。
* 对于一些inter指令,Inter处理器提供了很多LOCK前缀的指令,通过在指令前面加LOCK指令,会对缓存加锁,保证其他处理器不能同时访问数据。
* java中可以通过锁和循环CAS的方式来实现原子操作,java current包中的类大多是通过CAS方式实现的,CAS是基于处理器CMPXCHG指令。
* 在java中除了偏向锁(锁的等级分为无锁、偏向锁、轻量级锁、重量级锁),其他锁的方式都是通过CAS方式实现的。
* AtomicReference类来保证引用对象之间的原子性,你可以把多个变量放在一个对象里来进行CAS操作,对于这个对象的操作的原子性。
* 原子操作会有ABA的问题,当CompareAndSet时,比较的变量会有A-B-A的过程,则为false。通过添加版本号,变为A1-B2-A3。
* CAS是通过循环操作比较的,无限循环会大量消耗cpu。CAS一次只能操作一个变量,现在通过atomicReference,可以原子改变一个对象状态。
* AQS是一种思想,线程安全的集合用到了AQS思想,锁的实现是通过CAS实现的。通过AQS实现ReetrantLock的lock和unlock的过程,具体的lock获取,unlock通过CAS实现的。
* AQS - abstractQueueSynchronized,通过队列的方式管理lock,lock的实现通过CAS具体实现的。
* @author pc
*
*/
public class AtomicTest {
public AtomicInteger atomicI = new AtomicInteger(0);// 使用CAS操作,保证原子性。
public int i = 0;
public void unSafe(){
i++;
}
public void safeCount(){
for(;;){
int i = atomicI.get();
boolean flag = atomicI.compareAndSet(i, ++i);
if (flag){
break;
}
}
}
public static void main(String[] args){
final AtomicTest test = new AtomicTest();
/**
* final 的作用保证在多线程中的不可变性,即可以在多线程中直接使用
* final 关键字提高了性能,java应用和JVM都会缓存final关键字的变量
*
*/
List<Thread> list = new ArrayList<Thread>();
for(int j = 0; j < 1000; j++){
Thread t = new Thread(new Runnable(){
public void run(){
test.unSafe();
test.safeCount();
}
});
list.add(t);
}
for(Thread thread : list){
thread.start();
}
System.out.println(test.i);// 不能保证原子性,在同一时刻可能有多个线程修改i这个变量。
System.out.println(test.atomicI.get());// 保证了原子性,输出1000,在同一时刻只有一个线程修改这个atomicInteger这个变量。
}
}
阅读全文
0 0
- java锁的理解
- java synchronized锁的理解
- java 线程锁对象锁的理解
- java中锁的深入理解(一)
- java中锁的深入理解(二)
- java多线程的理解
- Java多态性的理解
- 理解java的异常
- 理解java的File
- 理解java的clone
- java 多态性的理解
- java引用的理解
- JAVA时间的理解
- java-servlet的理解
- java虚拟机的理解
- java接口的理解
- Java的finally理解
- Java内存的理解
- Nginx之Location配置详解(Location匹配顺序)
- java学习第43天,重写hashcode
- 【UWP开发】如何判断UWP应用在PC还是在xbox上运行?
- python文件操作
- 电脑快捷键大全
- java锁的理解
- leetcode 84|85. Largest Rectangle in Histogram | Maximal Rectangle
- 51nod 1135 原根
- es6->数据结构
- 数据结构第九周项目(二)——二叉树遍历的递归算法
- 第八周 【项目1
- 谈谈spring中的拦截器interceptor
- webService简单实例
- AtCoder Beginner Contest 076 D