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

学网站建设需要用哪几个软件建设银行官方网首页

学网站建设需要用哪几个软件,建设银行官方网首页,一个网站多个域名备案,网站设计制作软件文章目录 1. 十八罗汉2. 原子类再分类2.1 基本类型原子类2.2 数组类型原子类2.3 引用类型原子类2.4 对象的属性修改原子类2.5 原子操作增强类 3. 代码演示及性能比较#xff1a;4. LongAddr原理5. LongAddr源码分析5.1 add()5.2 longAccumulate()5.3 sum() 6. 小总结6.1 Atomi… 文章目录 1. 十八罗汉2. 原子类再分类2.1 基本类型原子类2.2 数组类型原子类2.3 引用类型原子类2.4 对象的属性修改原子类2.5 原子操作增强类 3. 代码演示及性能比较4. LongAddr原理5. LongAddr源码分析5.1 add()5.2 longAccumulate()5.3 sum() 6. 小总结6.1 AtomicLong6.2 LongAdder 1. 十八罗汉 底层使用Unsafe类的CAS方法而无需使用synchronized等重量锁使操作变得线程安全 AtomicBooleanAtomicIntegerAtomicIntegerArrayAtomicIntegerFieldUpdaterAtomicLongAtomicLongArrayAtomicLongFieldUpdaterAtomicMarkableReferenceAtomicReferenceAtomicReferenceArrayAtomicReferenceFieldUpdaterAtomicStampedReferenceDoubleAccumulatorDoubleAdderLongAccumulatorLongAdderStriped64LongAdder是Striped64的子类NumberStriped64AtomicInteger等是Number的子类 2. 原子类再分类 2.1 基本类型原子类 AtomicBooleanAtomicIntegerAtomicLong 基本使用 public class Temp {static int num 0;static AtomicInteger atomicNum new AtomicInteger();public static void main(String[] args) throws InterruptedException {int size 50;CountDownLatch count new CountDownLatch(size);for (int i 0; i size; i) {new Thread(() - {try {for (int j 0; j 1000; j) {num;atomicNum.getAndIncrement();}} finally {count.countDown();}}).start();}count.await();System.out.println(num);System.out.println(atomicNum.get());} }输出 39224 500002.2 数组类型原子类 如何理解类比数组即可 AtomicIntegerArrayAtomicLongArrayAtomicReferenceArray 2.3 引用类型原子类 AtomicReferenceAtomicStampedReference 用版本号解决CAS的ABA问题可以统计出修改过几次 AtomicMarkableReference 用状态戳解决CAS的ABA问题可以标记出是否修改过 2.4 对象的属性修改原子类 AtomicIntegerFieldUpdater原子更新对象中int类型字段的值AtomicLongFieldUpdater原子更新对象中Long类型字段的值AtomicReferenceFieldUpdater原子更新对象中引用类型字段的值 目的以一种线程安全的方式操作非线程安全对象内的某些字段 要求 更新的对象属性必须使用public volatile修饰使用静态放法newUpdater()创建一个更新器并且需要设置想要更新的类和属性 /*** 需求多线程环境下初始化资源类要求只能初始化一次*/ public class Temp {public volatile Boolean isInit Boolean.FALSE;private static final AtomicReferenceFieldUpdaterTemp, Boolean ATOMIC_REFERENCE_FIELD_UPDATER AtomicReferenceFieldUpdater.newUpdater(Temp.class, Boolean.class, isInit);public void init(Temp temp) {if (ATOMIC_REFERENCE_FIELD_UPDATER.compareAndSet(temp, Boolean.FALSE, Boolean.TRUE)) {System.out.println(Thread.currentThread().getName():init start);try { TimeUnit.SECONDS.sleep(1); } catch (Exception e) {}System.out.println(Thread.currentThread().getName():init finished);} else {System.out.println(Thread.currentThread().getName():已有线程正在初始化);}}public static void main(String[] args) throws InterruptedException {int size 5;CountDownLatch count new CountDownLatch(size);Temp temp new Temp();for (int i 0; i size; i) {new Thread(() - {try {temp.init(temp);} finally {count.countDown();}}).start();}count.await();} }2.5 原子操作增强类 DoubleAccumulator一个或多个变量共同维护使用的函数更新的运行double值DoubleAdder一个或多个变量共同维持最初的零和double总和LongAccumulator一个或多个变量共同维护使用的函数更新的运行long值LongAdder一个或多个变量共同维持最初的零和long总和 volatile 解决多线程内存不可见问题。对于一写多读是可以解决变量同步问题但是如果多写同样无法解决线程安全问题。 说明: 如果是 count操作使用如下类实现: AtomicInteger count new AtomicInteger0;count.addAndGet(1);如果是JDK8推荐使用 LongAdder 对象比 AtomicLong 性能更好( 减少乐观锁的重试次数 )同时使用LongAdder的空间代价更大故越是高并发越推荐使用LongAdder 。 LongAdder只能用来计算加法且从零开始计算 LongAccumulator提供了自定义函数的操作且可以传入初始值。 3. 代码演示及性能比较 /*** 需求点赞数统计50个线程每个点赞1千万次*/ public class Temp {long i 0;public synchronized void synchronizedIncrement() {i;}AtomicLong atomicLong new AtomicLong();public void atomicLongIncrement() {atomicLong.getAndIncrement();}LongAdder longAdder new LongAdder();public void longAdderIncrement() {longAdder.increment();}LongAccumulator longAccumulator new LongAccumulator(Long::sum, 0);public void longAccumulatorIncrement() {longAdder.increment();}public static void main(String[] args) throws InterruptedException {int threadNum 50;int times 10000000;process(threadNum, times, 1);process(threadNum, times, 2);process(threadNum, times, 3);process(threadNum, times, 4);}public static void process(int threadNum, int times, int type) throws InterruptedException {long startTime System.currentTimeMillis();CountDownLatch countDownLatch new CountDownLatch(threadNum);Temp temp new Temp();for (int i 0; i threadNum; i) {new Thread(() - {try {for (int j 0; j times; j) {switch (type) {case 1: temp.synchronizedIncrement();break;case 2: temp.atomicLongIncrement();break;case 3: temp.longAdderIncrement();break;case 4: temp.longAccumulatorIncrement();break;default: throw new RuntimeException(不存在的类型);}}} finally {countDownLatch.countDown();}}).start();}countDownLatch.await();long endTime System.currentTimeMillis();System.out.println(costTime: (endTime - startTime) 毫秒 typeStr(type));}public static String typeStr(int type) {switch (type) {case 1: return synchronizedIncrement;case 2: return atomicLongIncrement;case 3: return longAdderIncrement;case 4: return longAccumulatorIncrement;default: throw new RuntimeException(不存在的类型);}} }执行结果 costTime:22854 毫秒synchronizedIncrement costTime:4888 毫秒atomicLongIncrement costTime:215 毫秒longAdderIncrement costTime:214 毫秒longAccumulatorIncrement4. LongAddr原理 LongAddr继承了Striped64LongAdder的基本思路就是分散热点将value值分散到一个Cell数组中不同线程会命中到数组的不同槽中各个线程只对自己槽中的那个值进行CAS操作这样热点就被分散了冲突的概率就小很多。如果要获取真正的long值只要将各个槽中的变量值累加返回 sum()会将所有Cell数组中的value和base累加作为返回值核心的思想就是将之前AtomicLong一个value的更新压力分散到多个value中去 从而降级更新热点。 Striped64比较重要的成员变量 /** Number of CPUS, to place bound on table size * CPU数量即cells数组的最大长度*/static final int NCPU Runtime.getRuntime().availableProcessors();/*** Table of cells. When non-null, size is a power of 2.* cells数组长度为2的幂24816...方便以后位运算*/transient volatile Cell[] cells;/*** Base value, used mainly when there is no contention, but also as* a fallback during table initialization races. Updated via CAS.* 基础value值当并发较低时只累加该值主要用于没有竞争的情况通过CAS更新*/transient volatile long base;/*** Spinlock (locked via CAS) used when resizing and/or creating Cells.* 创建或扩容Cells数组时使用的自旋锁变量调整单元格大小(扩容)创建单元格时使用的锁*/transient volatile int cellsBusy;5. LongAddr源码分析 小总结LongAdder在无竞争的情况跟AtomicLong一样对同一个base进行操作当出现竞争关系时则是采用化整为零分散热点的做法用空间换时间用一个数组cells将一个value拆分进这个数组cells。多个线程需要同时对value进行换作时候可以对线程id进行hash得到hash值再根据hash值映射到这个数组cells的某个下标再对该下标所对应的值进行自增操作。当所有线程换作完毕将数组cells的所有值和base都加起来作为最终结果 5.1 add() public void add(long x) {// as是Striped64中的cells数组属性// b是Striped64中的base属性// v是当前线程hash到Cell中存储的值// m是cells的长度-1hash时作为掩码使用// a是当前线程hash到的CellCell[] as; long b, v; int m; Cell a;// 首次首线程(as cells) ! null一定是false此时走casBase方法以CAS的方式更新base值且只有当cas失败时才会走到if中// 条件1 cells不为空// 条件2 cas操作base失败说明其他线程先一步修改了base出现竞争if ((as cells) ! null || !casBase(b base, b x)) {// true无竞争false表示竞争激烈多个线程hash到同一个cell可能要扩容boolean uncontended true;// 条件1cells为空// 条件2应该不会出现// 条件3当前线程所在cell为空说明当前线程还没有更新过cell应初始化一个cell// 条件4更新当前线程所在cell失败说明竞争很激烈多个线程hash到了同一个cell应扩容if (as null || (m as.length - 1) 0 ||// getProbe()方法返回的是线程中的threadLocalRandomProbe字段// 它是通过随机数生成的一个值对于一个确定的线程这个值是固定的(除非刻意修改它)(a as[getProbe() m]) null ||!(uncontended a.cas(v a.value, v x)))longAccumulate(x, null, uncontended);} }5.2 longAccumulate() /*** Handles cases of updates involving initialization, resizing,* creating new Cells, and/or contention. See above for* explanation. This method suffers the usual non-modularity* problems of optimistic retry code, relying on rechecked sets of* reads.** param x the value * param fn the update function, or null for add (this convention* avoids the need for an extra field or function in LongAdder). * param wasUncontended false if CAS failed before call * x: 需要增加的值一般默认都是1* fn: 默认传递的是null* wasUncontended: 竞争标识如果是false标识有竞争。只有cells初始化之后并且当前线程CAS修改失败才会是false*/final void longAccumulate(long x, LongBinaryOperator fn,boolean wasUncontended) {// h存储线程的probe值int h;// 如果getProbe()方法返回0说明随机数未初始化if ((h getProbe()) 0) { // 这个操作相当于给当前线程生成一个非0的hash值// 使用ThreadLocalRandom为当前线程重新计算一个hash值强制初始化ThreadLocalRandom.current(); // force initialization// 重新获取probe值hash值被重置就好比一个全新的线程一样所以设置了wasUncontended竞争状态为trueh getProbe();// 重新计算了当前线程的hash后认为此次不算是一次竞争都未初始化肯定还不存在竞争激烈故设置wasUncontended竞争状态为truewasUncontended true;}// 如果hash取模映射得到的cell单元不是null则为true此值也可以看做是扩容意向boolean collide false; // True if last slot nonemptyfor (;;) {// 自旋按CASE 2,3,1看代码Cell[] as; Cell a; int n; long v;// CASE 1cells已经被初始化了if ((as cells) ! null (n as.length) 0) {// CASE 1.1 :当前线程hash到的cell还未初始化则需要进行初始化处理初始化的值为x即默认的1if ((a as[(n - 1) h]) null) {if (cellsBusy 0) { // Try to attach new CellCell r new Cell(x); // Optimistically create// 双端检查并尝试抢锁if (cellsBusy 0 casCellsBusy()) {boolean created false;try { // Recheck under lockCell[] rs; int m, j;if ((rs cells) ! null (m rs.length) 0 rs[j (m - 1) h] null) {rs[j] r;created true;}} finally {cellsBusy 0;}if (created)break;continue; // Slot is now non-empty}}collide false;}// CASE 1.2竞争激烈允许重新计算hash值else if (!wasUncontended) // CAS already known to failwasUncontended true; // Continue after rehash// CASE 1.3当前线程hash到已初始化的槽位使用cas进行更新更新成功则跳出循环else if (a.cas(v a.value, ((fn null) ? v x :fn.applyAsLong(v, x))))break;// CASE 1.4如果cells的长度已经大于等于CPU核数就不要再扩容了,继续hash;cells ! as说明已有线程正在扩容else if (n NCPU || cells ! as)collide false; // At max size or stale// CASE 1.5将扩容意向置为true如果再hash仍然不满足上诉条件便扩容else if (!collide)collide true;// CASE 1.6尝试扩容将老数组复制到新数组上else if (cellsBusy 0 casCellsBusy()) {try {// 当前的cells数组和最先赋值的as是同一个代表没有被其他线程扩容过if (cells as) { // Expand table unless staleCell[] rs new Cell[n 1];for (int i 0; i n; i)rs[i] as[i];cells rs;}} finally {cellsBusy 0;}collide false;continue; // Retry with expanded table}// 允许重置当前线程的hash值h advanceProbe(h);}// CASE 2cells没有加锁且没有初始化则尝试对它进行加锁并初始化cells数组;cellsBusy0表示无锁状态cellsBusy1为持锁状态else if (cellsBusy 0 cells as casCellsBusy()) {// boolean init false;try { // Initialize tableif (cells as) {// 与条件中cells as形成双重检查Cell[] rs new Cell[2];rs[h 1] new Cell(x); // 按照当前线程hash到数组中的位置并创建其对应的Cellcells rs;init true;}} finally {cellsBusy 0;}if (init)break;}// CASE 3cells正在进行初始化则尝试直接在基数base上进行累加操作兜底操作当新线程进来而数组正在初始化时则用base进行累加else if (casBase(v base, ((fn null) ? v x :fn.applyAsLong(v, x))))break; // Fall back on using base}}5.3 sum() /*** Returns the current sum. The returned value is emNOT/em an* atomic snapshot; invocation in the absence of concurrent* updates returns an accurate result, but concurrent updates that* occur while the sum is being calculated might not be* incorporated.** return the 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;}sum执行时并没有限制对base和cells的更新。所以LongAdder不是强一致性的它是最终一致性的 6. 小总结 6.1 AtomicLong 原理CAS自旋 场景低并发下的全局计算AtomicLong能保证并发情况下计数的准确性内部使用CAS来解决并发安全问题 缺陷高并发后性能急剧下降N个线程CAS操作修改线程的值每次只有一个成功其它N-1失败失败的不停的自旋直到成功这样大量失败自旋的情况很浪费CPU资源 6.2 LongAdder 原理CASBaseCell数组分散空间换时间并分散了热点数据 场景高并发下的全局计算 缺陷sum求和时还有计算线程修改结果的话最后的结果不够准确
http://www.dnsts.com.cn/news/121354.html

相关文章:

  • 网站设计制作教程美食网站建设规划书
  • 汉中市住建局建设厅网站官网网站建设人员需求
  • 怎么做传奇网站图设计基础网站推荐
  • 如何制作自己的网站书签page如何转换为wordpress
  • 网站建设 电商网站建设国内外研究现状
  • 邢台专业网站建设推荐移动云服务器租用
  • 网站建设模块是什么怎么做微信公众号文章
  • 龙游网站建设的公司wordpress 最新文章展示
  • 网站建设公司哪里好网站设计公司北京
  • 技术支持 东莞网站建设页面设计说明怎么写
  • 三明网站建设tudouly河北省建设机械会网站
  • 推荐10个优秀的国外ui设计网站免费做长图网站
  • 网站建设项目实施计划书wordpress 用户中心主题
  • 公司网站开发建设深圳网站营销公司简介
  • 国内装饰行业网站开发欧洲十大服务器的推荐
  • 潍坊做网站软件免费的素材网站
  • 个人建设网站程序自己建网站流程要学什么
  • 怎么选择网站模板东营市建设监理协会网站
  • 做外贸要建什么网站苏州工业园区建设网站
  • 06年可以做相册视频的网站wordpress中文转英文版
  • wordpress 站长工具付费ppt模板网站哪个好
  • 太原网站建设哪家好wordpress访问量大
  • 连锁店管理网站开发wordpress图片用阿里云储存
  • 想在网上做开发网站接活儿世界著名办公室设计
  • 自己怎么做 优惠券网站做一个自己的网站流程
  • dw 做网站模板建设银行手机版官方网站下载
  • 网站如何做搜索引擎优化外网访问不了内网建设的网站
  • 北京国互网网站建设报价PHP网站开发都需要学什么
  • 购物网站免费模板郴州优化公司
  • 软件网站开发团队名称wordpress控制面板都没