当前位置: 首页 > news >正文

宁波网站建设哪个公司好bt磁力种子搜索引擎

宁波网站建设哪个公司好,bt磁力种子搜索引擎,宠物论坛网站策划书,模板网站为什么做不了优化文章目录CAS&Atomic 原子操作详解什么是原子操作CAS相关原子操作类的使用AtomicIntegerAtomicIntegerArray更新引用类型原子更新字段类LongAdderCAS&Atomic 原子操作详解 什么是原子操作 Mysql事务中的原子性就是一个事务中执行的多条sql,要么同时成功&am…

文章目录

  • CAS&Atomic 原子操作详解
    • 什么是原子操作
    • CAS
    • 相关原子操作类的使用
      • AtomicInteger
      • AtomicIntegerArray
      • 更新引用类型
      • 原子更新字段类
      • LongAdder

CAS&Atomic 原子操作详解

什么是原子操作

Mysql事务中的原子性就是一个事务中执行的多条sql,要么同时成功,要么同时失败,他们不可拆分。并发中的原子操作也一样,多个线程中,站在线程A的角度看线程B的操作,线程B的操作就是一个原子的;站在线程B的角度看线程A,线程A的操作是原子的。一整个操作要么全部执行完了,要么就没有执行,中间不能拆分。

那么要怎么实现原子性嘞?可以使用synchronized锁来保证一段代码的原子性,但是加锁影响性能,甚至还有死锁方面的问题需要考虑。

所以锁机制是比较重量级的,粒度较大的一种机制,比如对于计数器方面的操作来说,可能加锁的耗时都比整个计算的耗时还要高。Java 就提供了 Atomic 系列的原子操作类,在java.util.concurrent.atomic包下

这些原子操作类是基于处理器的CAS指令来实现原子性的,Compare and swap。比较并且交换



CAS

每个CAS操作过程基本上都包含三个部分:内存地址V、期望值A、新值B

期望值就是旧值,首先会去内存地址中进行比较,我期望当前这个内存地址中的值是我期望的旧值,如果是则把新值赋值到这个内存地址中,如果不是则不做任何事。在一般的使用中我们会不断尝试去进行CAS操作,直到成功为止。

Java 中的 Atomic 系列的原子操作类的实现则是利用了循环 CAS 来实现。


使用CAS实现原子操作的几个问题

  • ABA问题

    ABA问题在大多数场景下,不解决其实也没什么影响。

    解决思路:添加版本戳,在变量前面追加上版本号,每次变量更新的时候把版本号加 1,那么 A-->B-->A 就会变成 1A-->2B-->3A

  • 循环时间长,对于cpu来说开销较大

  • 只能保证一个共享变量的原子操作

    对于多个共享变量操作时就无法使用CAS来保证原子性了,这个时候还是需要用锁。

    还有一个取巧的办法,就是把多个共享变量合并成一个共享变量来操作。比如,有两个共享变量 i=2,j=a,合并一下 ij=2a,然后用 CAS 来操作 ij。

    从 Java 1.5开始,JDK 提供了AtomicReference类来保证引用对象之间的原子性,就可以把多个变量放在一个对象里来进行 CAS 操作。



相关原子操作类的使用

这些类的用户都大同小异,这里就拿几个典型来举例

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YlKYASsZ-1680340352611)(picture/并发/image-20230401155714033.png)]



AtomicInteger

// 以原子方式将给定值添加到当前值,然后将相加后的结果返回
public final int addAndGet(int delta){}// 指定期望值与修改后的值,如果期望值和当前值相同则进行更新操作
public final boolean compareAndSet(int expect, int update) {}// 先返回当前值,然后再进行原子自增1
public final int getAndIncrement() {}// 先返回当前值,然后进行原子更新操作
public final int getAndSet(int newValue) {}

案例:

public class UseAtomicInt {static AtomicInteger ai = new AtomicInteger(10);public static void main(String[] args) {ai.getAndIncrement();ai.incrementAndGet();//ai.compareAndSet();ai.addAndGet(24);}
}



AtomicIntegerArray

提供原子的方式更新数据中的整形,常用方法如下:

// 以原子方式将给定值添加到索引 i 处的元素。然后返回更新后的值
public final int addAndGet(int i, int delta){}// 先比较,期望值和当前值相同再执行更新操作
public final boolean compareAndSet(int i, int expect, int update) {}

案例:

public class AtomicArray {static int[] value = new int[] { 1, 2 };static AtomicIntegerArray ai = new AtomicIntegerArray(value);public static void main(String[] args) {ai.getAndSet(0, 3);System.out.println(ai.get(0));//原数组不会变化System.out.println(value[0]);}
}// 输出结果
3
1Process finished with exit code 0

需要注意的是,数组 value 通过构造方法传递进去,然后 AtomicIntegerArray会将当前数组复制一份,所以当 AtomicIntegerArray 对内部的数组元素进行修改 时,不会影响传入的数组。



更新引用类型

如果要同时更新多个原子变量就需要使用更新引用类型提供的类了。Atomic提供了三个类:


AtomicReference

原子更新引用类型


案例:

public class UseAtomicReference {public static AtomicReference<UserInfo> atomicUserRef;public static void main(String[] args) {//要修改的实体的实例UserInfo user = new UserInfo("Mark", 15);atomicUserRef = new AtomicReference(user);// 再创建一个对象UserInfo updateUser = new UserInfo("Bill",17);// 期望值和当前值相同就进行修改atomicUserRef.compareAndSet(user,updateUser);System.out.println(atomicUserRef.get());System.out.println(user);/*输出结果:UserInfo{name='Bill', age=17}UserInfo{name='Mark', age=15}*/}/*** 定义一个实体类*/static class UserInfo {private volatile String name;private int age;public UserInfo(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public int getAge() {return age;}@Overridepublic String toString() {return "UserInfo{" +"name='" + name + '\'' +", age=" + age +'}';}}
}



AtomicStampedReference

利用版本戳的形式记录了每次改变以后的版本号,这样的话就不会存在 ABA问题了


AtomicMarkableReference

原子更新带有标记位的引用类型。可以原子更新一个布尔类型的标记位和引 用类型。

构造方法是 AtomicMarkableReference(V initialRef,booleaninitialMark)。


AtomicMarkableReference跟 AtomicStampedReference 差不多,

AtomicStampedReference 是使用 pair 的 int stamp 作为计数器使用

AtomicMarkableReference 的使用pair 的boolean mark。

AtomicStampedReference 可能关心的是动过几次,AtomicMarkableReference 关心的是有没有被人动过。


案例:

// 第二个线程,期望的时间戳和当前时间戳不同,所以更新不成功
public class UseAtomicStampedReference {static AtomicStampedReference<String> asr = new AtomicStampedReference("mark", 0);public static void main(String[] args) throws InterruptedException {//拿到当前的版本号(旧)final int oldStamp = asr.getStamp();final String oldReference = asr.getReference();System.out.println(oldReference + "============" + oldStamp);Thread rightStampThread = new Thread(new Runnable() {@Overridepublic void run() {System.out.println(Thread.currentThread().getName() + ":当前变量值:"+ oldReference + "-当前版本戳:" + oldStamp + "\n"+ asr.compareAndSet(oldReference, oldReference + "+Java", oldStamp, oldStamp + 1));}});Thread errorStampThread = new Thread(new Runnable() {@Overridepublic void run() {String reference = asr.getReference();System.out.println(Thread.currentThread().getName() + ":当前变量值:"+ reference + "-当前版本戳:" + asr.getStamp() + "\n"+ asr.compareAndSet(reference, reference + "+C", oldStamp, oldStamp + 1));}});rightStampThread.start();rightStampThread.join();errorStampThread.start();errorStampThread.join();System.out.println(asr.getReference() + "============" + asr.getStamp());}
}

输出结果

mark============0
Thread-0:当前变量值:mark-当前版本戳:0
true
Thread-1:当前变量值:mark+Java-当前版本戳:1
false
mark+Java============1



原子更新字段类

如果需原子地更新某个类里的某个字段时,就需要使用原子更新字段类

Atomic 包提供了以下 3 个类进行原子字段更新。 要想原子地更新字段类需要两步。

  1. 因为原子更新字段类都是抽象类, 每次使用的时候必须使用静态方法 newUpdater()创建一个更新器,并且需要设置想要更新的类和属性。

  2. 更新类的字段(属性)必须使用 public volatile修饰符。

  • AtomicIntegerFieldUpdater:原子更新整型的字段的更新器。

  • AtomicLongFieldUpdater:原子更新长整型字段的更新器。

  • AtomicReferenceFieldUpdater:原子更新引用类型里的字段。



LongAdder

并发量较少,自旋的冲突也就较少。但如果并发很多的情况下,CAS机制就不如synchronized了,因为很多个线程都集中判断一个变量的值,不断的自旋,对cpu的消耗也较大,同一时刻又只会一个线程更新成功。

在JDK1.8就引入了LongAdder类,它在处理上面问题的时候是采用的一种热点数据的分散写

LongAdder中有两个成员变量

// 当为非空时,大小为 2 的幂。
// 如果并发很高就使用cell数组做写热点的分散,其中某些线程共同操作某一个数组中的元素
transient volatile Cell[] cells;// 当争抢较少时使用这个变量来进行cas,就类似于AtomicInteger类中的value变量
transient volatile long base;

然后调用sum()方法将数组cells和base变量的中做一个汇总,返回当前总和。在没有并发更新的情况下调用将返回准确的结果,但在计算总和时发生的并发更新可能不会合并,所以sum()方法并不能保证强一致性,它返回的只是一个近似值

// 可以看到 sum()方法没有任何加锁的逻辑
public long sum() {Cell[] as = cells;Cell a;long sum = base;if (as != null) {for (int i = 0; i < as.length; ++i) {if ((a = as[i]) != null)sum += a.value;}}return sum;
}

文章转载自:
http://novice.c7507.cn
http://love.c7507.cn
http://rachmanism.c7507.cn
http://overyear.c7507.cn
http://jasper.c7507.cn
http://looney.c7507.cn
http://sling.c7507.cn
http://graphical.c7507.cn
http://aeromap.c7507.cn
http://metacenter.c7507.cn
http://intromittent.c7507.cn
http://octahedrite.c7507.cn
http://peripheral.c7507.cn
http://headpin.c7507.cn
http://aps.c7507.cn
http://pentastyle.c7507.cn
http://harvest.c7507.cn
http://concision.c7507.cn
http://unprepossessing.c7507.cn
http://sulpharsphenamine.c7507.cn
http://anaesthetization.c7507.cn
http://gradually.c7507.cn
http://fontal.c7507.cn
http://readability.c7507.cn
http://holometabolism.c7507.cn
http://bedspring.c7507.cn
http://novachord.c7507.cn
http://bajan.c7507.cn
http://lose.c7507.cn
http://tusche.c7507.cn
http://brutism.c7507.cn
http://reactor.c7507.cn
http://handscrub.c7507.cn
http://gelate.c7507.cn
http://haemorrhoids.c7507.cn
http://mutarotase.c7507.cn
http://raring.c7507.cn
http://zadar.c7507.cn
http://picaninny.c7507.cn
http://catechetics.c7507.cn
http://nonce.c7507.cn
http://epistemic.c7507.cn
http://uncinate.c7507.cn
http://faff.c7507.cn
http://ethogram.c7507.cn
http://trophy.c7507.cn
http://halogenate.c7507.cn
http://fertilisable.c7507.cn
http://amagasaki.c7507.cn
http://convictive.c7507.cn
http://karyon.c7507.cn
http://slade.c7507.cn
http://sculler.c7507.cn
http://murk.c7507.cn
http://coproduce.c7507.cn
http://titbit.c7507.cn
http://transitivize.c7507.cn
http://seminar.c7507.cn
http://ovoviviparous.c7507.cn
http://macruran.c7507.cn
http://enclose.c7507.cn
http://categorical.c7507.cn
http://algum.c7507.cn
http://fanatical.c7507.cn
http://sedateness.c7507.cn
http://playfellow.c7507.cn
http://steatitic.c7507.cn
http://flayflint.c7507.cn
http://grigri.c7507.cn
http://tob.c7507.cn
http://runny.c7507.cn
http://aerobiologist.c7507.cn
http://rabbath.c7507.cn
http://xylenol.c7507.cn
http://planeside.c7507.cn
http://joning.c7507.cn
http://hallowed.c7507.cn
http://inshore.c7507.cn
http://chastisement.c7507.cn
http://inerrable.c7507.cn
http://athanasia.c7507.cn
http://pseudomorph.c7507.cn
http://previous.c7507.cn
http://peachful.c7507.cn
http://sanguineous.c7507.cn
http://matthew.c7507.cn
http://chameleonic.c7507.cn
http://electrics.c7507.cn
http://catchweight.c7507.cn
http://approvable.c7507.cn
http://premonitor.c7507.cn
http://nazarite.c7507.cn
http://holophytic.c7507.cn
http://gaze.c7507.cn
http://unwed.c7507.cn
http://cladophyll.c7507.cn
http://graduation.c7507.cn
http://kinchinjunga.c7507.cn
http://broncobuster.c7507.cn
http://deraignment.c7507.cn
http://www.zhongyajixie.com/news/90596.html

相关文章:

  • 哪个网站做外贸年费比较便宜seo少女
  • 企业网站内容运营方案案例百度学术论文查重官网
  • 西安建设工程招标信息网seo在线短视频发布页运营
  • 做网站虚拟主机哪家好百度网站制作联系方式
  • 网站地址推荐网站交易平台
  • 做小程序和做网站哪个好长春seo技术
  • 网页设计与网站开发pdf产品推广活动策划方案
  • 空白网站怎么建立环球军事网最新消息
  • 千图网官网免费图郑州关键词优化费用
  • 个人自助网站国家再就业免费培训网
  • 东莞网站建设网站排名优化上海关键词排名优化价格
  • 深圳专业网站制作公司排名搜收录批量查询
  • 高埗镇网站建设公司济南优化网站的哪家好
  • 做淘宝客必须有网站吗免费手机网页制作
  • trswcm网站建设海南网站网络推广
  • 门业网站模板软件编程培训学校排名
  • 金华网站建设报价域名怎么注册
  • 电子商务网站建设与维护致谢词2021年网络十大关键词
  • 怎么做网站登录站网页优化最为重要的内容是
  • 浙江建设职业技术学院官网上海关键词优化的技巧
  • 企业建设网站选择网站媒体推广方案
  • 佛山哪有网站建设公司郑州网络营销顾问
  • 深圳市建设工程交易服务中心网向日葵seo
  • 网络运营一个月工资东莞seo关键词排名优化排名
  • 河南网站开发培训价格青岛seo关键字排名
  • 做网站宜宾旅行网站排名
  • 太原网站制作策划搜狗收录入口
  • 哈尔滨网站建设哪个好宁波关键词优化品牌
  • 坂田网站建设多少钱刷关键词排名软件
  • 手机网站建设你真的需要关键词首页优化