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

qq客服代码放在网站哪里/建什么网站可以长期盈利

qq客服代码放在网站哪里,建什么网站可以长期盈利,2018爱情动做网站,做动态网站不需要DW吗一、CAS什么是CAS,CAS就是Compare and SwapCAS是一种无锁算法原理:对CAS的理解,CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存…

一、CAS

什么是CAS,CAS就是Compare and Swap

CAS是一种无锁算法

原理:

对CAS的理解,CAS是一种无锁算法,CAS有3个操作数,内存值V,旧的预期值A,要修改的新值B。当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

举个例子,表示一下CAS的原理。假设t1在与t2线程竞争中线程t1能去更新变量的值,而其他线程都失败。(失败的线程并不会被挂起,而是被告知这次竞争中失败,并可以再次发起尝试)。t1线程去更新变量值改为57,然后写到内存中。此时对于t2来说,内存值变为了57,与预期值56不一致,就操作失败了(想改的值不再是原来的值)。

代码:

public final int getAndAddInt(Object var1, long var2, int var4) {

//1 操作的对象,2 对象中字段的偏移量,3 原来的值,4 要修改的值。

int var5;

do {

var5 = this.getIntVolatile(var1, var2);//得到当前的值。

} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

return var5;

}

上面的代码是原子类中的一个例子。

ABA问题:

CAS乐观锁机制确实能够提升吞吐,并保证一致性,但在极端情况下可能会出现ABA问题。就是期望值被从A改为B,又从B改为A.CAS还能成功。

解决方法:加版本号。

二、原子类

原子类,顾名思义就是不可分割的,当原子类去执行操作的话是一步合成的。

以前的时候我们并发操作的时候,回去选择加锁。加锁还是有很多影响的。比如:性能损耗、逻辑复杂。所以在JDK1.5的时候Doug Lea写了原子类,也是在JUC包下。

1、原子类介绍

1.1、原子更新基本类型

下面是三种基本原子类型,以及他们常用的API。

AtomicInteger atomicInteger = new AtomicInteger(1);

atomicInteger.getAndAdd(1); //以原子方式将给定值添加到当前值。

atomicInteger.compareAndSet(1,2); //如果当前值==期望值,则以原子方式将该值设置为给定的更新值。

atomicInteger.get(); //获取当前值

atomicInteger.getAndIncrement(); //以原子方式将当前值增加一。

atomicInteger.getAndDecrement(); //以原子方式将当前值减一。

atomicInteger.addAndGet(2); //以原子方式将给定值添加到当前值。

atomicInteger.weakCompareAndSet(1,2); //如果当前值==期望值,则以原子方式将该值设置为给定的更新值。可能会虚假地失败,并且不提供排序保证,因此,很少是compareAndSet的适当替代方法。

AtomicBoolean atomicBoolean = new AtomicBoolean();

atomicBoolean.lazySet(true); //最终设置为给定值。

AtomicLong atomicLong = new AtomicLong(1L);

atomicLong.addAndGet(2L); //以原子方式将给定值添加到当前值。

//基本和Integer相似,就不一一列举了。

总的来说,它们的底层都使用了CAS,我们来找一个看看。

atomicInteger.addAndGet(2);

//第一层

public final int addAndGet(int delta) {

return unsafe.getAndAddInt(this, valueOffset, delta) + delta;

}

//第二层

public final int getAndAddInt(Object var1, long var2, int var4) {

int var5;

do {

var5 = this.getIntVolatile(var1, var2); //预期值

} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4)); //var4是我们想要增加的值

return var5; //注意这个var5是加var4之前的值。

}

1.2、原子更新数组

我们再来看一下原子更新数组的一些基本操作

AtomicIntegerArray array = new AtomicIntegerArray(16);

array.set(1,16); //将位置i的元素设置为给定值。

array.addAndGet(1,13); //以原子方式将给定值添加到索引i处的元素。

System.out.println(array.get(1)); //获取位置i的当前值。

AtomicLongArray longArray = new AtomicLongArray(16);

// 基本和AtomicIntegerArray的API相似

longArray.set(1,2);

我们看一下AtomicIntegerArray的内部原理

public AtomicIntegerArray(int length) { //我们看一下初始化方法,内部就是维护了一个private final int[] array;

array = new int[length];

}

看一下array.addAndGet(1,13);这个方法的内部原理。

//第一层

public final int addAndGet(int i, int delta) {

return getAndAdd(i, delta) + delta;

}

//第二层

public final int getAndAdd(int i, int delta) {

return unsafe.getAndAddInt(array, checkedByteOffset(i), delta);

}

private long checkedByteOffset(int i) {

if (i < 0 || i >= array.length)

throw new IndexOutOfBoundsException("index " + i);

return byteOffset(i);

}

//第三层

public final int getAndAddInt(Object var1, long var2, int var4) {

int var5;

do {

var5 = this.getIntVolatile(var1, var2);

} while(!this.compareAndSwapInt(var1, var2, var5, var5 + var4));

return var5;

}

//还是调用的这个方法。

AtomicReferenceArray引用数组的基本使用方法。

AtomicReferenceArray referenceArray = new AtomicReferenceArray(16);

referenceArray.set(1, "222");

//将给定函数应用于当前值和给定值,以原子方式更新索引i处的元素,并返回更新后的值。

// 该功能应无副作用,因为当尝试更新由于线程之间的争用而失败时,可以重新应用该功能。

// 应用该函数时,将索引i处的当前值作为其第一个参数,并将给定的update作为第二个参数。

referenceArray.accumulateAndGet(1, "999", (x, y) -> x.toString() + y);

//输出结果为222999

我们看一下这个方法内部原理。

public final E accumulateAndGet(int i, E x,

BinaryOperator accumulatorFunction) {

long offset = checkedByteOffset(i); //获取下标在数组中的偏移量

E prev, next;

do {

prev = getRaw(offset); //获取当前的值

next = accumulatorFunction.apply(prev, x); //获取函数执行后的值

} while (!compareAndSetRaw(offset, prev, next)); //CAS赋值。

return next;

}

1.3、原子更新属性、引用。

原子的更新某个类里面的字段时,需要使用原子更新字段类。

我们来看看有一个原子类型。

AtomicStampedReference、AtomicReference、FiledUpdater。

不过使用上述几个引用,有几个规则必须遵守

字段必须是voliatile类型的,在线程之间共享变量时能保持可见性。

字段的描述类型是与调用者的操作对象字段保持一致。

也就是说调用者可以直接操作对象字段,那么就可以反射进行原子操作。

对父类的字段,子类不能直接操作的,尽管子类可以访问父类的字段。

只能是实例变量,不能是类变量,也就是说不能加static关键字。

只能是可修改变量,不能使用final修饰变量,final的语义,不可更改。

对于AtomicIntegerFieldUpdater和AtomicLongFieldUpdater只能修改int/long类型的字段,不能修改其包装类型(Integer/Long)

AtomicLongFieldUpdater这个只对long进行更新的使用方法。

AtomicLongFieldUpdater updater = AtomicLongFieldUpdater.newUpdater(Son.class, "id");

Son son = new Son();

son.setId(9);

updater.addAndGet(son,7);

如果我们想更改包装类,就使用AtomicReferenceFieldUpdater

AtomicReferenceFieldUpdater fieldUpdater = AtomicReferenceFieldUpdater.newUpdater(Son.class,String.class,"name");

fieldUpdater.compareAndSet(son,"777","666");

AtomicStampedReference 前面我们提到了ABA问题并且提到了解决办法就是加版本号,这个原子类就是带版本号的。

AtomicStampedReference stampedReference = new AtomicStampedReference("aaa", 1);

stampedReference.compareAndSet("aaa", "bbb", stampedReference.getStamp(), stampedReference.getStamp() + 1);

小结

我们去看原子类内部时,发现最终都是使用了CAS的方法。原子类就是在CAS发展来的。

http://www.lbrq.cn/news/745381.html

相关文章:

  • 什么网站出项目找人做/微信怎么推广
  • 广州网站建设公司排行/seo流量排行榜神器
  • 盐城网页制作哪家好/快速排名优化推广手机
  • 网站推广策划包含的内容/无锡seo关键词排名
  • 建网站怎么做报分系统/长安seo排名优化培训
  • 谷歌seo技巧/郑州seo外包顾问
  • 贾汪区人民政府门户网站建设/淘宝关键词指数
  • 网页模板下载网站10/线下引流的八种推广方式
  • 扬州外贸网站建设/app平台搭建
  • 关于设计的网站/西安百度推广排名
  • 常熟网络推广/seo是对网站进行什么优化
  • 湖北专业网站建设市面价/网络营销工具与方法
  • 建设通网站查询单位/百度认证营销推广师
  • wordpress插件直播/搜索引擎关键词优化有哪些技巧
  • 青岛微网站开发/有没有专门帮人推广的公司
  • 北京城乡建设官方网站/公司网站设计制作
  • 珠海做网站哪家专业/百度云搜索
  • 培训网络营销的机构/北京seo优化wyhseo
  • 响应式网站设计案例/b站视频推广网站400
  • 网站的在线客服系统/网站建设平台哪家好
  • 中央疫情二十条措施最新/爱站网seo查询
  • 青岛市建设厅网站/简短的软文范例
  • wordpress博客类似/seo推广有哪些
  • 自己做行程的网站/宁波seo排名外包公司
  • 奇米网怎么做网站/被国家禁止访问的网站怎么打开
  • 做网站备案要多久/长沙今日头条新闻
  • p2p网站如何做测试/东莞疫情最新消息今天
  • 网站默认图片素材/电工培训技术学校
  • 怎么给网站做链接/互联网广告平台有哪些
  • 面试问你如何快速优化网站/财经新闻最新消息
  • 小程序插件使用
  • 哈希:两数之和
  • 用随机森林填补缺失值:原理、实现与实战
  • Android中使用RxJava实现网络请求与缓存策略
  • 力扣438:找到字符串中所有的字母异位词
  • 多维视角下离子的特性、应用与前沿探索