java 分离锁_锁分类(独占锁、分拆锁、分离锁、分布式锁)

在共享内存的多处理器体系架构中,每个处理器都拥有自己的缓存,并且定期地与主内存进行协调。

在不同的处理器架构中提供了不同级别的缓存一致性(Cache Coherence),

其中一部分只提供最小的保证,即允许不同的处理器在任意时刻从同一个存储位置上看到不同的值。

操作系统、编译器以及运行时(有时甚至包括应用程序)需要弥合这种在硬件能力与线程安全之间的差异。

java内存模型

抽象出线程独有的运行内存和共有的主存储

为了使java开发人员无须关心不同架构内存模型之间的差异,

Java还提供了自己的内存模型,并且JVM通过在适当的位置上插入内存栅栏(内存屏障)来屏蔽在JVM与底层之平台内存模型之间的差异。

线程中的变量何时同步回到内存是不可预期的

java内存模型规定,通过关键词”synchronized“、”volatile“可以让java保证某些约束。

“volatile” - 保证读写的都是主内存变量。

“synchronized” - 保证在块开始时,都同步主内存值到工作内存,而快结束时,将工作内存同步会主内存。

指令重排序::

public class PossibleReordering {

static int x = 0, y = 0;

static int a = 0, b = 0;

public static void main(String[] args) throws InterruptedException {

Thread one = new Thread(new Runnable() {

@Override

public void run() {

a = 1;

x = b;

}

});

Thread two = new Thread(new Runnable() {

@Override

public void run() {

b = 2;

y = a;

}

});

one.start();

two.start();

one.join();

two.join();

System.out.println("x:" + x + ",y:" + y);

}

}

执行结果,一般人可能认为是1,1;真正的执行结果可能每次都不一样。

拜JMM重排序所赐,JMM使得不同线程的操作顺序是不同的,

从而导致在缺乏同步的情况下,要推断操作的执行结果将变得更加复杂。

同步将限制编译器和硬件运行时对内存操作重排序的方式。

锁synchronized

锁实现了对临界资源的互斥访问,是严格的排它锁、互斥锁。

JVM规范通过两个内存屏障(memory barrier)命令来实现排它逻辑。

内存屏障可以理解成顺序执行的一组CPU指令,完全无视指令重排序。

类锁(锁是TestSTatic.class对象)、对象锁

独占锁

如果你不敢确定该用什么锁,就用这个吧,在保证正确的前提下,后续在提高开发效率。

分拆锁

如果将这些锁请求分到更多的锁上,就能有效降低锁竞争程度。

由于等待而被阻塞的线程将更少,从而可伸缩性将提高。

同时使用俩

分离锁

在某些情况下,可以将锁分解技术进一步扩展为对一组独立对象上的锁进行分解,这种情况称为锁分段

例如ConcurrencyHashMap是有一个包含16个锁的数组实现

锁分段的劣势在于:

与采用单个锁来实现独占访问相比,

要获取多个锁来实现独占访问将更加困难并且开销更高,

比如计算size、重hash。

分布式锁

zookeeper,判断临时节点是否存在,存在就说明已经有人争抢到锁;

不存在就创建节点,表明拥有该锁。

volatile

volatile是比synchronized更轻量级的同步原语,

volatile可以修饰实例变量、静态变量、以及数组变量(引用)。

被volatile修饰的变量,JVM规范规定,一个线程在修改完,另外的线程能读取最新的值。

仅仅保证可见性,不保证原子性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值