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

专项培训网站建设方案免费做问卷的网站

专项培训网站建设方案,免费做问卷的网站,wordpress一栏多图,中英文网站栏目修改原子类 JDK提供的原子类#xff0c;即Atomic*类有很多#xff0c;大体可做如下分类#xff1a; 形式类别举例Atomic*基本类型原子类AtomicInteger、AtomicLong、AtomicBooleanAtomic*Array数组类型原子类AtomicIntegerArray、AtomicLongArray、AtomicReferenceArrayAtomic…原子类 JDK提供的原子类即Atomic*类有很多大体可做如下分类 形式类别举例Atomic*基本类型原子类AtomicInteger、AtomicLong、AtomicBooleanAtomic*Array数组类型原子类AtomicIntegerArray、AtomicLongArray、AtomicReferenceArrayAtomic*Reference引用类型原子类AtomicReference、AtomicStampedReference、AtomicMarkableReferenceAtomic*FieldUpdater升级类型原子类AtomicIntegerFieldUpdater、AtomicLongFieldUpdater、AtomicReferenceFieldUpdater*Adder自增器LongAdder、DoubleAdder*Accumulator累加器LongAccumulator、DoubleAccumulator 引入原因 JDK为何要引入如此多的原子类API。 因为Java中的运算操作如自增()或自减(–)都不是原子性操作若没有进行额外的同步操作在多线程环境下就是线程不安全。给变量增加volatile关键词也不管用。 volatile的作用是 可见性对volatile变量所有的写操作都能立即反应到其他线程中有序性禁止指令的重排序优化。 并不能保证自增或自减操作的原子性。 AtomicLong JDK1.5引入的AtomicLong作用是对长整形对象进行原子操作。类似地AtomicInteger用于对整形对象进行原子操作AtomicBoolean用于对Boolean对象进行原子操作。这几个API的方法非常相似。 示例 直接给出代码 public class AtomicLongExample {private static final AtomicLong counter new AtomicLong();public static void increment() {counter.incrementAndGet();}public static long get() {return counter.get();} }可知实现起来非常简单。 原理 看看AtomicLong.incrementAndGet()源码 public class AtomicLong extends Number implements Serializable {private static final Unsafe U Unsafe.getUnsafe();private static final long VALUE U.objectFieldOffset(AtomicLong.class, value);public final long incrementAndGet() {return U.getAndAddLong(this, VALUE, 1L) 1L;} }继续看Unsafe类的getAndAddLong方法 IntrinsicCandidate public final long getAndAddLong(Object o, long offset, long delta) {long v;do {v getLongVolatile(o, offset);} while (!weakCompareAndSetLong(o, offset, v, v delta));return v; }IntrinsicCandidate public native long getLongVolatile(Object o, long offset);// weakCompareAndSetLong方法最后调用 IntrinsicCandidate public final native boolean compareAndSetLong(Object o, long offset, long expected, long x);最后是调用native方法。通过Unsafe的CAS指令实现线程安全地、原子性自增操作。 问题 这里提前给出结论这也是JDK1.8引入LongAdder类的原因 在多线程竞争不激烈的情况下这样做是合适的。但是如果线程竞争激烈会造成大量线程在原地打转、不停尝试去修改值但再次发现值已被修改于是继续自旋。浪费大量的CPU资源。 AtomicLong持有的成员变量value是volatile关键字修饰的线程修改临界资源后需要刷新到其他线程也是要费一番功夫的。 严重情况下volatile可能导致总线风暴问题。 AtomicReference AtomicReference是JDK1.5开始提供的一种用于原子操作对象引用的类位于java.util.concurrent.atomic包。提供一种非阻塞的线程安全方式来更新和读取对象引用使用的是底层的原子操作来保证操作的原子性。 适用场景 非阻塞算法在多线程环境下需要实现高效、低延迟的非阻塞算法时AtomicReference是一个很好的选择。它通过CAS操作避免传统锁机制的开销适用于对性能要求高的场景引用类型的原子更新当需要对引用类型如对象的更新操作保持原子性时可使用AtomicReference。例如在单例模式中通过CAS操作来确保单例实例的唯一性构建高效的并发数据结构可以用于构建各种并发数据结构如无锁队列、无锁栈、无锁链表等实现不可变对象的原子替换对于不可变对象可使用AtomicReference实现原子替换操作保证在多线程环境下的安全性。例如引用类型的配置更新确保配置更新的原子性和可见性。 实例 使用AtomicReference实现简单CAS操作 Slf4j public class AtomicReferenceExample {public static void main(String[] args) {AtomicReferenceString atomicString new AtomicReference(initialValue);log.info(Current value: atomicString.get());// 使用compareAndSet原子更新值boolean success atomicString.compareAndSet(initialValue, newValue);log.info(Updated value: atomicString.get());// 直接设置新值atomicString.set(anotherValue);log.info(Directly set value: atomicString.get());} }可知和AtomicLong非常相似。 原理 CAS操作(Compare-And-Set)基于硬件支持的CAS原子操作实现。这种操作包括三个步骤比较当前值是否等于预期值如果相等则将其更新为新值如果不相等则不进行任何操作。CAS是一种无锁(lock-free)算法可避免传统锁机制带来的性能问题和死锁风险。内存可见性使用volatile关键字确保引用变量的可见性。所有对AtomicReference的写操作都会立即对所有线程可见读取操作也总是能获取最新的值。 AtomicReference提供的一系列方法 get()获取当前的引用值set(V newValue)设置当前引用值为新值lazySet(V newValue)惰性设置为新值compareAndSet(V expect, V update)如果当前引用值等于预期值则将其更新为新值getAndSet(V newValue)获取当前引用值并设置为新值weakCompareAndSet(V expect, V update)类似于compareAndSet但在一些平台上可能有更高的性能weakCompareAndSetPlain(V expectedValue, V newValue)getAndUpdate(UnaryOperatorV updateFunc)updateAndGet(UnaryOperatorV updateFunc)getAndAccumulate(V x, BinaryOperatorV accumulatorFunc)accumulateAndGet(V x, BinaryOperatorV accumulatorFunc) JDK9又新增一系列方法 getPlainsetPlaingetOpaquesetOpaquegetAcquiresetReleasecompareAndExchangecompareAndExchangeAcquirecompareAndExchangeReleaseweakCompareAndSetVolatileweakCompareAndSetAcquireweakCompareAndSetRelease 总结 AtomicReference是一种高效、线程安全的工具用于在并发环境中进行原子引用操作。它依赖于CAS操作来实现无锁的原子性更新适用于构建高性能的并发数据结构和非阻塞算法。在实际应用中可根据具体需求选择使用AtomicReference来替代传统的锁机制以提高并发程序的性能和可靠性。 AtomicIntegerFieldUpdater AtomicXXXFieldUpdater是JDK提供的一种用于更新对象中某些字段值的工具提供一种低开销、高性能的方式来对对象的字段进行原子操作。适合某些特定场景尤其是在需要对对象的整型字段实现线程安全更新时。包括AtomicIntegerFieldUpdater、AtomicLongFieldUpdater和AtomicReferenceFieldUpdater。下面以AtomicIntegerFieldUpdater为例讲解。 适用场景 高性能计数器或标志位更新需要频繁更新对象中的某个计数器或标志字段但又不想将整个对象进行锁定基于 POJO 对象的非静态字段更新如果字段不能声明为 AtomicInteger如 POJO 中的普通整型字段AtomicIntegerFieldUpdater 提供了原子化更新的方法内存优化场景相比直接使用AtomicInteger通过AtomicIntegerFieldUpdater不需要为每个整型字段额外创建一个AtomicInteger对象避免锁开销替代传统的synchronized或ReentrantLock减少线程间竞争和锁的性能开销。适合高并发环境下的小粒度操作共享对象字段的线程安全管理在缓存、计数器池等场景中共享对象的某个字段需要被多个线程安全地读写。 AtomicIntegerFieldUpdater的核心优势在于提供对对象字段的原子操作节省内存减少锁开销。适用于高性能的计数或标志更新场景但由于功能较为有限更多的复杂线程同步需求可能需要其他工具如Lock或ConcurrentHashMap。 示例 假设需要对某个对象的int字段count进行线程安全的递增操作 public class Example {// 字段必须是volatile、非静态、int基础类型private volatile int count;// 创建 AtomicIntegerFieldUpdaterprivate static final AtomicIntegerFieldUpdaterExample updater AtomicIntegerFieldUpdater.newUpdater(Example.class, count);public int increment() {return updater.incrementAndGet(this); // 原子递增}public int get() {return updater.get(this); // 获取值}public static void main(String[] args) {Example example new Example();log.info(example.increment()); // 输出1} }原理 AtomicIntegerFieldUpdater是一个抽象泛型类构造函数是protected不能直接构造其对象必须通过它提供的一个静态方法来创建 // 受保护的不执行任何操作的构造函数供子类使用 protected AtomicIntegerFieldUpdater() { }CallerSensitive public static U AtomicIntegerFieldUpdaterU newUpdater(ClassU tclass, String fieldName) {return new AtomicIntegerFieldUpdaterImplU(tclass, fieldName, Reflection.getCallerClass()); }newUpdater()静态方法传入的是要修改的类和对应的成员变量的名字内部通过反射拿到这个类的成员变量然后包装成一个AtomicIntegerFieldUpdater对象即AtomicIntegerFieldUpdaterImpl。所以这个对象表示的是类的某个成员而不是对象的成员变量。 然后可使用其一系列方法 compareAndSetweakCompareAndSetsetlazySetgetgetAndSetgetAndIncrementgetAndDecrementgetAndAddincrementAndGetdecrementAndGetaddAndGetgetAndUpdateupdateAndGetgetAndAccumulateaccumulateAndGet 以getAndAdd方法为例其源码如下 public int getAndAdd(T obj, int delta) {int prev, next;do {prev get(obj);next prev delta;} while (!compareAndSet(obj, prev, next));return prev; }get方法如下 public final int get(T obj) {accessCheck(obj);return U.getIntVolatile(obj, offset); }compareAndSet方法如下 public final boolean compareAndSet(T obj, int expect, int update) {accessCheck(obj);return U.compareAndSetInt(obj, offset, expect, update); }accecssCheck方法检查该obj是不是cclass类型如果不是则拒绝修改并抛出异常。 U是Unsafe使用其CAS方法参考Unsafe入门讲解。 AtomicIntegerFieldUpdaterImpl是一个静态私有内部实现类Impl其构造函数为 AtomicIntegerFieldUpdaterImpl(final ClassT tclass, final String fieldName, final Class? caller) {final Field field;final int modifiers;try {field AccessController.doPrivileged(new PrivilegedExceptionActionField() {public Field run() throws NoSuchFieldException {return tclass.getDeclaredField(fieldName);}});modifiers field.getModifiers();sun.reflect.misc.ReflectUtil.ensureMemberAccess(caller, tclass, null, modifiers);ClassLoader cl tclass.getClassLoader();ClassLoader ccl caller.getClassLoader();if ((ccl ! null) (ccl ! cl) ((cl null) || !isAncestor(cl, ccl))) {sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass);}} catch (PrivilegedActionException pae) {throw new RuntimeException(pae.getException());} catch (Exception ex) {throw new RuntimeException(ex);}if (field.getType() ! int.class)throw new IllegalArgumentException(Must be integer type);if (!Modifier.isVolatile(modifiers))throw new IllegalArgumentException(Must be volatile type);// 受保护字段成员的访问仅限于访问类或其子类之一的接收者并且访问类又必须是受保护成员定义类的子类或包兄弟// 如果更新程序引用当前包之外的声明类的受保护字段则接收者参数将缩小到访问类的类型this.cclass (Modifier.isProtected(modifiers) tclass.isAssignableFrom(caller) !isSamePackage(tclass, caller)) ? caller : tclass;this.tclass tclass;this.offset U.objectFieldOffset(field); }可知要想使用AtomicIntegerFieldUpdater修改成员变量成员变量必须是volatile的int类型不能是包装类。 对比 工具特点适用场景AtomicIntegerFieldUpdater低内存开销对对象的字段进行原子更新对对象的单一字段进行高性能原子操作AtomicInteger独立对象的原子更新使用简单但需要额外的内存空间独立计数器或标志位synchronized/Lock适合复杂的临界区保护复杂的线程同步逻辑LongAdder提供高并发场景下的高效累加器减少线程争用高并发场景的全局计数器 LongAdder JDK1.8中新加入一个原子类LongAdder该类可保证Long类型操作的原子性。相对于AtomicLongLongAdder有着更高的性能减少乐观锁的重试次数和更好的表现可完全替代AtomicLong来进行原子操作。 当大量线程同时访问AtomicLong时会因为大量线程执行CAS操作失败而进行空旋转导致CPU资源消耗过多执行效率不高。 示例 直接给出代码 public class LongAdderExample {private static final LongAdder counter new LongAdder();public static void increment() {counter.increment();}public static long get() {return counter.sum();} }可见实现起来非常简单。 原理 基于CAS分段锁的思想实现的。线程去读写一个LongAdder类型的变量时的流程 LongAdder基于Unsafe提供的CAS操作valitale去实现的。在LongAdder的父类Striped64中维护着base变量和cells数组当多个线程操作一个变量时先会在这个base变量上进行CAS操作当它发现线程增多时就会使用cells数组。比如当base将要更新时发现线程增多调用casBase方法更新base值失败则会自动使用cells数组每一个线程对应于一个cell在每一个线程中对该cells进行CAS操作这样就可以将单一value的更新压力分担到多个value中去降低单个value的热度同时也减少大量线程的空转提高并发效率分散并发压力。这种分段锁需要额外维护一个内存空间cells在高并发场景下这点成本几乎可忽略。 利用空间来换时间将热点value分散成一个Cell列表来承接并发的CAS以此来提升性能。 Benchmark 一个简单不太严谨的Benchmark性能测试 Slf4j public class AtomicLongTester {private static AtomicLong numA new AtomicLong(0);private static LongAdder numB new LongAdder();public static void main(String[] args) throws InterruptedException {for (int i 1; i 10001; i*10) {test(false, i);test(true, i);}}public static void test(boolean isLongAdder, int threadCount) throws InterruptedException {long starTime System.currentTimeMillis();final CountDownLatch latch new CountDownLatch(threadCount);for (int i 0; i threadCount; i) {new Thread(new Runnable() {public void run() {for (int i 0; i 100000; i) {if (isLongAdder) {numB.add(1);} else {numA.addAndGet(1);}}latch.countDown();}}).start();}// 等待所有运算结束 latch.await();if (isLongAdder) {log.info(Thread Count threadCount , LongAdder cost ms (System.currentTimeMillis() - starTime) , Result numB.sum());} else {log.info(Thread Count threadCount , AtomicLong cost ms (System.currentTimeMillis() - starTime) , Result numA.get());}numA new AtomicLong(0);numB new LongAdder();} }某次运行结果 Thread Count1, AtomicLong cost ms9, Result100000 Thread Count1, LongAdder cost ms13, Result100000 Thread Count10, AtomicLong cost ms14, Result1000000 Thread Count10, LongAdder cost ms41, Result1000000 Thread Count100, AtomicLong cost ms111, Result10000000 Thread Count100, LongAdder cost ms45, Result10000000 Thread Count1000, AtomicLong cost ms1456, Result100000000 Thread Count1000, LongAdder cost ms379, Result100000000 Thread Count10000, AtomicLong cost ms17452, Result1000000000 Thread Count10000, LongAdder cost ms3545, Result1000000000可见当线程竞争率比较低时AtomicLong效率优于LongAdder的但当线程竞争率增大时可看出LongAdder的性能远远高于AtomicLong。 对比 对比项AtomicLongLongAdder原理Unsafe类CAS指令分段累加使用内部的多个Cell类似于分段桶每个线程可独立更新不同Cell减少竞争空间开销只需一个long变量内存占用小内部包含多个Cell每个Cell是一个独立变量占用更多内存低并发更新只需要操作单一变量执行路径更短性能较优且实现简单需初始化多个Cell即使只有一个线程使用也需要额外的内存和初始化开销高并发多线程更新同一变量时频繁CAS重试会导致性能瓶颈减少线程争用吞吐量更高精度要求高更适合当需要获取总值时会将所有Cell的值汇总短时间内的结果可能不完全一致 LongAccumulator 有待学习。 参考
http://www.yingshimen.cn/news/64561/

相关文章:

  • 网站开发维护合同样板免费做app网站建设
  • 以下属于网站seo的内容是58同城网站建设规划
  • 中国水电建设招标网站网站建设美工百度百科
  • 长沙有网站建站吗百度站长平台有哪些功能
  • 广州哪个公司做网站好陈铭生
  • 网站对网友发帖隐私做处理网络科技网站有哪些方面
  • 做同款的网站网站受到攻击
  • 自己做网站开店企业网站推广的重要性
  • 郑州网站建设哪里好ASP.NET商业级数据库网站开发实战
  • 成都行业网站建设免费pc网站建设
  • 对外贸易企业网站建设流程网上定做衣服的网站
  • 论文网站建设目标网站外链数怎么查
  • 建设申请网站首页wordpress 百家号
  • 网站建设推广熊掌号太原建高铁站
  • 西安网站制作价格石家庄上门足疗
  • 官方你网站建设策略深圳市龙岗区住房和建设局官网网站
  • 网站建设的重点网站程序
  • 网站开发研究热点wordpress水平菜单
  • 网站空间大小多少合适网站流量统计数据库设计
  • 慈溪市网站开发大石桥城乡规划建设局网站
  • 网站建设短期培训青海省教育厅门户网站首页
  • 烟台专业的做网站公司服装网站建设方案
  • 快速提高网站权重百度浏览器官网在线使用
  • 主题 外贸网站 模板下载asp源码下载网站
  • 泊头市做网站价格产品宣传片公司
  • 企业网站的seo太原免费静态网页制作网站
  • 特产网站开发的好处网站建设优化学习
  • 和县网站制作个体工商户经营范围网站开发
  • 百度竞价点击神器桂平seo关键词优化
  • 和田网站建设公司主页网站设计