java replace [ 一文足以了解什么是 Java 中的锁
java replace [ 一文足以了解什么是 Java 中的锁
Java 锁分类
Java 中的锁有很多,可以按照不同的功能、种类进行分类,下面是我对 Java 中一些常用锁的分类,包括一些基本的概述

下面我们依次对各个锁的分类进行详细阐述。
线程是否需要对资源加锁
Java 按照是否对资源加锁分为乐观锁和悲观锁,乐观锁和悲观锁并不是一种真实存在的锁,而是一种设计思想,乐观锁和悲观锁对于理解 Java 多线程和数据库来说至关重要,下面就来探讨一下这两种实现方式的区别和优缺点
悲观锁
悲观锁是一种悲观思想,它总认为最坏的情况可能会出现,它认为数据很可能会被其他人所修改,所以悲观锁在持有数据的时候总会把资源 或者 数据 锁住java replace [ 一文足以了解什么是 Java 中的锁,这样其他线程想要请求这个资源的时候就会阻塞,直到等到悲观锁把资源释放为止。传统的关系型数据库里边就用到了很多这种锁机制,**比如行锁,表锁等,读锁,写锁等,都是在做操作之前先上锁。**悲观锁的实现往往依靠数据库本身的锁功能实现。
Java 中的 和 等独占锁(排他锁)也是一种悲观锁思想的实现,因为 和 不管是否持有资源,它都会尝试去加锁,生怕自己心爱的宝贝被别人拿走。
乐观锁
乐观锁的思想与悲观锁的思想相反,它总认为资源和数据不会被别人所修改,所以读取不会上锁,但是乐观锁在进行写入操作的时候会判断当前数据是否被修改过(具体如何判断我们下面再说)。乐观锁的实现方案一般来说有两种:版本号机制 和 CAS实现 。乐观锁多适用于多读的应用类型,这样可以提高吞吐量。
在Java中
java.util..包下面的原子变量类就是使用了乐观锁的一种实现方式 CAS 实现的。
两种锁的使用场景

上面介绍了两种锁的基本概念,并提到了两种锁的适用场景,一般来说,悲观锁不仅会对写操作加锁还会对读操作加锁,一个典型的悲观锁调用:
select * from student where name="cxuan" for update这条 sql 语句从 表中选取 name = "cxuan" 的记录并对其加锁,那么其他写操作再这个事务提交之前都不会对这条数据进行操作,起到了独占和排他的作用。
悲观锁因为对读写都加锁java replace [ 一文足以了解什么是 Java 中的锁,所以它的性能比较低,对于现在互联网提倡的三高(高性能、高可用、高并发)来说java replace [,悲观锁的实现用的越来越少了,但是一般多读的情况下还是需要使用悲观锁的,因为虽然加锁的性能比较低,但是也阻止了像乐观锁一样,遇到写不一致的情况下一直重试的时间。
相对而言,乐观锁用于读多写少的情况,即很少发生冲突的场景,这样可以省去锁的开销,增加系统的吞吐量。
乐观锁的适用场景有很多,典型的比如说成本系统java replace [,柜员要对一笔金额做修改,为了保证数据的准确性和实效性,使用悲观锁锁住某个数据后,再遇到其他需要修改数据的操作,那么此操作就无法完成金额的修改,对产品来说是灾难性的一刻,使用乐观锁的版本号机制能够解决这个问题,我们下面说。
乐观锁的实现方式
乐观锁一般有两种实现方式:采用版本号机制 和 CAS(-and-Swap,即比较并替换)算法实现。
版本号机制
版本号机制是在数据表中加上一个 字段来实现的,表示数据被修改的次数,当执行写操作并且写入成功后, = + 1,当线程A要更新数据时,在读取数据的同时也会读取 值,在提交更新时,若刚才读取到的 值为当前数据库中的值相等时才更新,否则重试更新操作,直到更新成功。
我们以上面的金融系统为例,来简述一下这个过程。
上面两种情况是最乐观的情况,上面的两个事务都是顺序执行的,也就是事务一和事务二互不干扰,那么事务要并行执行会如何呢?
事务一开启,男柜员先执行读操作,取出金额和版本号,执行写操作
begin
update 表 set 金额 = 120,version = version + 1 where 金额 = 100 and version = 0
此时金额改为 120,版本号为1,事务还没有提交
事务二开启,女柜员先执行读操作,取出金额和版本号,执行写操作
begin
update 表 set 金额 = 50,version = version + 1 where 金额 = 100 and version = 0此时金额改为 50,版本号变为 1,事务未提交
现在提交事务一,金额改为 120,版本变为1,提交事务。理想情况下应该变为 金额 = 50,版本号 = 2,但是实际上事务二 的更新是建立在金额为 100 和 版本号为 0 的基础上的,所以事务二不会提交成功,应该重新读取金额和版本号,再次进行写操作。
这样,就避免了女柜员 用基于 = 0 的旧数据修改的结果覆盖男操作员操作结果的可能。
CAS 算法
省略代码,完整代码请参照 看完你就应该能明白的悲观锁和乐观锁
CAS 即 and swap(比较与交换)java replace [,是一种有名的无锁算法。即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(Non-
Java 从 JDK1.5 开始支持,java.util. 包里提供了很多面向并发编程的类,也提供了 CAS 算法的支持,一些以 为开头的一些原子类都使用 CAS 作为其实现方式。使用这些类在多核 CPU 的机器上会有比较好的性能。
如果要保证它们的原子性,必须进行加锁,使用 或者 ,我们前面介绍它们是悲观锁的实现,我们现在讨论的是乐观锁,那么用哪种方式保证它们的原子性呢?请继续往下看
CAS 中涉及三个要素:
当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。
我们以 java.util. 中的 为例,看一下在不用锁的情况下是如何保证线程安全的
public class AtomicCounter {
private AtomicInteger integer = new AtomicInteger;
public AtomicInteger getInteger {
return integer;
}
public voidsetInteger(AtomicInteger integer) {
this.integer = integer;
}
public voidincrement{
integer.incrementAndGet;
}
public voiddecrement{
integer.decrementAndGet;
}
}
public class AtomicProducer extendsThread{
private AtomicCounter atomicCounter;
publicAtomicProducer(AtomicCounter atomicCounter){
this.atomicCounter = atomicCounter;
}
@Override
public voidrun {
for(int j = 0; j < AtomicTest.LOOP; j++) {
System.out.println("producer : " + atomicCounter.getInteger);
atomicCounter.increment;
}
}
}
public class AtomicConsumer extendsThread{
private AtomicCounter atomicCounter;
publicAtomicConsumer(AtomicCounter atomicCounter){
this.atomicCounter = atomicCounter;
}
@Override
public voidrun {
for(int j = 0; j < AtomicTest.LOOP; j++) {
System.out.println("consumer : " + atomicCounter.getInteger);
atomicCounter.decrement;
}
}
}
public class AtomicTest {
final static int LOOP = 10000;
public static void main(String[] args) throws InterruptedException {
AtomicCounter counter = new AtomicCounter;
AtomicProducer producer = new AtomicProducer(counter);
AtomicConsumer consumer = new AtomicConsumer(counter);
producer.start;
consumer.start;
producer.join;
consumer.join;
System.out.println(counter.getInteger);
}
}公告:
1. 本站所有资源来源于用户上传和网络,如有侵权请联系站长!
2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
5. 如有链接无法下载、失效或广告,请联系站长处理!
6. 本站不售卖代码,资源标价只是站长收集整理的辛苦费!如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。
7. 站长QQ号码 2205675299
资源库 - 资源分享下载网 » java replace [ 一文足以了解什么是 Java 中的锁常见问题FAQ
- 关于资源售价和售后服务的说明?
- 代码有没有售后服务和技术支持?
- 有没有搭建服务?
- 链接地址失效了怎么办?
- 关于解压密码




