zoukankan      html  css  js  c++  java
  • Java并发编程之——Amino框架

    Amino框架是一个采用无锁方式实现并行计算的框架,可惜的是,网上关于Amino框架的介绍甚少。根据所掌握的资料,稍微总结一下:

    1. 锁机制到无锁机制

    锁机制可以确保程序和数据的线程安全,但是锁是一种阻塞式的同步方式,无论是ReentrantLock、synchronized,还是Semaphore,都受到核心资源的限制。为避免这个问题,便提出了无锁的同步机制。
     

    2. 基于Compare-and-swap(CAS) 算法的无锁并发控制方法

    CAS算法过程是:它包含三个参数CAS(V,E,N),V表示内存位置目前的值,E表示期望的原值,N表示新值。当处理器要更新一个内存位置的值的时候,它首先将V与E进行对比(要知道在多处理的时候,你要更新的内存位置上的值V有可能被其他处理更新过,而你全然不知),如果V与E相同,那么就将V设为N,将N写入内存;否则,就什么也不做,不写入新的值(现在最新的做法是定义内存值的版本号,根据版本号的改变来判断内存值是否被修改)。CAS 的价值所在就在于它是在硬件级别实现的,速度那是相当的快。
    这种无锁并发控制方法像极了乐观锁。
     
    在JDK的java.util.concurrent.atomic包下,有一组使用无锁方式实现的原子操作,包括AtomicInteger、AtomicIntegerArray、AtomicLong、AtomicLongArray等。以AtomicInteger为例,其中的getAndSet()方法是这样实现CAS的:
     
    [java] view plain copy
     
    1. public final int getAndSet(int newValue){  
    2.     for(;;){  
    3.         int current=get();  
    4.         if(compareAndSet(current,newValue))  
    5.             return current;  
    6.     }  
    7. }  
     

    3. 引出Amino框架

    该组件将提供一套免锁的集合类(LockFreeVector、LockFreeList、LockFreeSet等)、树结构、图结构。因为这些数据结构采用免锁的运算法则来生成,所以,它们将拥有基本的免锁组件的特性,如可以避免不同类型的死锁,不同类型的线程初始化顺序等。 
     
    Amino 还提供了一些非常有用的并行计算模式,包括 Master-Worker、Map-reduce、Divide and conquer, Pipeline 等。 
     
    Amino并没有加入到官方jdk中,因此需要自行下载、导入。
    下载地址:http://sourceforge.net/projects/amino-cbbs/files/
     

    4. 性能测试

    下面,在64位4G内存的Windows7测试下Vector与LockFreeVector、CopyOnWriteArrayList与LockFreeList在增加、删除操作的区别。从结果可以看出,后者性能大大提升。
     
    测试代码:
    [java] view plain copy
     
    1. public class CopyList {  
    2.     public static void test1(AccessListTread t, String name){  
    3.         CounterPoolExecutor exe0=new CounterPoolExecutor(2000,2000,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());  
    4.         exe0.TASK_COUNT=8000;  
    5.         exe0.funcname=name;  
    6.         exe0.startTime=System.currentTimeMillis();  
    7.         for(int i=0;i<exe0.TASK_COUNT;i++)  
    8.             exe0.submit(t);//测试数据:8000  
    9.         exe0.shutdown();  
    10.     }  
    11.     public static void main(String[] args) {  
    12.         AccessListTread t=new AccessListTread();  
    13.         t.initCopyOnWriteArrayList();  
    14.         test1(t,"testCopyOnWriteArrayList");  
    15.         t.initVector();  
    16.         test1(t,"testVector");  
    17.         t.initLockFreeList();  
    18.         test1(t,"testLockFreeList");  
    19.         t.initLockFreeVector();  
    20.         test1(t,"testLockFreeVector");  
    21.     }  
    22.       
    23. }  
    24. class CounterPoolExecutor extends ThreadPoolExecutor{  
    25.     public AtomicInteger count=new AtomicInteger(0);//统计次数  
    26.     public long startTime=0;  
    27.     public String funcname="";  
    28.     public int TASK_COUNT=0;  
    29.     public CounterPoolExecutor(int corePoolSize, int maximumPoolSize,  
    30.             long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) {  
    31.         super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);  
    32.     }  
    33.     @Override  
    34.     protected void afterExecute(Runnable r,Throwable t){  
    35.         int l=count.addAndGet(1);  
    36.         if(l==TASK_COUNT){  
    37.             System.out.println(funcname+"spend time:"+(System.currentTimeMillis()-startTime));  
    38.         }  
    39.     }  
    40. }  
    41.   
    42.   
    43.   
    44. class AccessListTread implements Runnable{  
    45.     Random rand=new Random();  
    46.     List list;  
    47.     public AccessListTread() {  
    48.     }  
    49.     @Override  
    50.     public void run() {  
    51.         try {  
    52.             for(int i=0;i<1000;i++)  
    53. //              getList(rand.nextInt(1000));  
    54.                 handleList(rand.nextInt(1000));  
    55.             Thread.sleep(rand.nextInt(100));  
    56.         } catch (InterruptedException e) {  
    57.             e.printStackTrace();  
    58.         }  
    59.     }  
    60.   
    61.     private Object getList(int nextInt) {  
    62.         return list.get(nextInt);  
    63.     }  
    64.     private Object handleList(int index) {  
    65.         list.add(index);  
    66.         list.remove(index%list.size());  
    67.         return null;  
    68.     }  
    69.     //test  
    70.     public void initCopyOnWriteArrayList(){  
    71.         list=new CopyOnWriteArrayList();  
    72.         for(int i=0;i<1000;i++)  
    73.             list.add(i);  
    74.     }  
    75.     public void initVector(){  
    76.         list=new Vector();  
    77.         for(int i=0;i<1000;i++)  
    78.             list.add(i);  
    79.     }  
    80.     public void initLockFreeList(){  
    81.         list=new LockFreeList();  
    82.         for(int i=0;i<1000;i++)  
    83.             list.add(i);  
    84.     }  
    85.     public void initLockFreeVector(){  
    86.         list=new LockFreeVector();  
    87.         for(int i=0;i<1000;i++)  
    88.             list.add(i);  
    89.     }  
    90. }  

    测试结果:
    [java] view plain copy
     
    1. testVectorspend time:366  
    2. testCopyOnWriteArrayListspend time:717  
    3. testLockFreeListspend time:541  
    4. testLockFreeVectorspend time:244  
  • 相关阅读:
    centos中安装docker
    docker es
    Linux 定时备份数据库
    Linux 防火墙firewalld
    Linux Systemd
    Linux at定时任务
    Linux运行级别
    原来这就是网络
    LeetCode-897-递增顺序搜索树
    SSM整合配置文件
  • 原文地址:https://www.cnblogs.com/toSeeMyDream/p/7227227.html
Copyright © 2011-2022 走看看