Padded优化LinkedTransferQue并发性能是错误方向

在Grizzly中,自带了LinkedTransferQueue,和JDK 7自带的LinkedTransferQueue有所不同,不同之处就是使用PaddedAtomicReference来提升并发性能,其实这是一种错误的编码技巧,没有意义!

AtomicReference和LinkedTransferQueue的本质是乐观锁,乐观锁的在激烈竞争的时候性能都很糟糕,乐观锁应使用在非激烈竞争的场景,为乐观锁优化激烈竞争下的性能,是错误的方向,因为如果需要激烈竞争,就应该使用悲观锁。

以下是一个JDK中内置乐观锁悲观锁的对照表:

乐观锁           ----->  悲观锁

AtomicInteger   ----->  Lock + volatile int

AtomicLong      ----->  Lock + volatile long

AtomicReference ----->  Lock + volatile

LinkedTransferQueue -----> LinkedBlockingQueue

在激烈竞争中,LinkedTransferQueue的性能,远远低于LinkedBlockingQueue,使用PaddedAtomicReference优化也是一样的。如果不激烈竞争,Padded-LinkedTransferQueue和LinkedTransferQueue相比也没有什么优势。

所以Padded-AtomicReference也是一个伪命题,如果激励竞争,为什么不使用Lock + volatile,如果非激烈竞争,使用PaddedAtomicReference对于AtomicReference又没有优势。所以使用Padded-AtomicReference是一个错误的编码技巧。

以下是测试代码,50个线程争用10个对象,这种激烈竞争下,使用LinkedTransferQueue比LinkedBlockingQueue大约慢10倍。

1package com.alibaba.study; 2 3import java.util.concurrent.*; 4 5public class BlockingQueueTest { 6 public static void main(String[] args) throws Exception { 7 for (int i = 0; i < 3; ++i) { 8 loop(); 9 } 10 } 11 12 private static void loop() throws InterruptedException { 13 final BlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(); 14// final BlockingQueue<Object> queue = new LinkedTransferQueue<Object>(); 15 16 for (int i = 0; i < 10; ++i) { 17 queue.put(i); 18 } 19 20 final int THREAD_COUNT = 50; 21 final CountDownLatch startLatch = new CountDownLatch(1); 22 final CountDownLatch endLatch = new CountDownLatch(THREAD_COUNT); 23 24 for (int i = 0; i < THREAD_COUNT; ++i) { 25 Thread thread = new Thread() { 26 public void run() { 27 try { 28 startLatch.await(); 29 } catch (InterruptedException e) { e.printStackTrace(); } 30 31 try { 32 for (int i = 0; i < 1000 * 20; ++i) { 33 Object item = queue.take(); 34 queue.put(item); 35 } 36 } catch (Exception e) { 37 e.printStackTrace(); 38 } finally { 39 endLatch.countDown(); 40 } 41 } 42 }; 43 thread.start(); 44 } 45 46 long startMillis = System.currentTimeMillis(); 47 startLatch.countDown(); 48 endLatch.await(); 49 long millis = System.currentTimeMillis() - startMillis; 50 System.out.println(queue.getClass().getName() + " : " + millis); 51 } 52}
点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

KVM调整cpu和内存

一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid

Padded优化LinkedTransferQue并发性能是错误方向 - HelloWorld