Amino框架无锁算法实现并发线程安装组件(一)

news2024/9/20 7:57:42

 Amino是无锁并行框架,线程安装,该框架封装了无锁算法,提供了可用于线程安全的一些数据结构,同时还内置了一些多线程调度模式。使用Amino进行软件开发有以下的优势:

1.对死锁的问题免疫

2.确保系统并发的整体进度

3.降低高并发下无锁竞争带来的性能开销

4.可以轻松使用一些成熟的无锁结构,而无需执行研发

有一种多线程同步的机制cas(compare and swap),他是基于操作系统的cas指令进行判断。

原理步骤:

1、先取出临界资源的值

2、接着将此值作为期望值,和临界值的最新值对比,如果相同,说明没有其他线程修改,直接更新;如果不相同,则说明被其他线程修改过了,回到步骤1继续

jdk内部已经实现了部分数据结构的cas无锁算法。比如AtomicInteger、AtomicIntegerArray、AtomicLong、AtomicLongArray、AtomicDouble、AtomicDoubleArray、AtomicBoolean。

但是没有对list、set、tree、Grap的实现。

Amino就是这样一款基于cas(compare and swap)无锁算法的框架,高并发,高性能。

提供了

list(LockFreeList、LockFreeVector)、

set(LockFreeSet)、

tree(LockFreeBSTree)、

Grap(UndirectedGrap)

2、Amino如何引入

不提供maven依赖,所以需要把源码下载,然后自己编译,最后把jar放到私服上即可引用。 源码下载地址:Concurrent Building Block - Browse /cbbs at SourceForge.net 编译放到maven私服,然后在pom.xml文件中引入即可融入执行项目进行整合开发,如下图所示:

3、如何使用

直接new 对应的类即可实现

list(LockFreeList、LockFreeVector)

set(LockFreeSet)

tree(LockFreeBSTree)

Grap(UndirectedGrap)

============================================================================

一.List

Amino提供了一组List的实现方式,其中最为重要的两种是LockFreeList和LockFreeVector,他们都实现了java.util.List接口;LockFreeList使用链表的作为底层的数据结构,实现了线程安全的无锁List,而LockFreeVector使用连续的数据作为底层数据结构,实现了线程安全的无锁Vector,LockFreeList和LockFreeVector的关系,就如同LinkedList和ArrayList一样;

下面我们是用LockFreeVector,LockFreeList,Vector,和实现线程安全的LinkedList进行了在高并发环境的性能进行对比。每一个测试线程AccessListThread对每一种List分别作1000次添加和删除操作:

===========================================================================

package org.jd.amino.concurrent.data.chat;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.amino.ds.lockfree.LockFreeSet;
import org.junit.Test;

public class TestLockFreeSet {
	private static final int MAX_THREADS = 2000;
	private static final int TASK_COUNT = 4000;
	java.util.Random rand=new java.util.Random();
	
	Set set;
	
	public class AccessSetThread implements Runnable{
		protected String name;
		
		public AccessSetThread(){
		}
		public AccessSetThread(String name){
			this.name=name;
		}
		@Override
		public void run() {
			try {
				for(int i=0;i<500;i++)
					handleSet(rand.nextInt(1000));
				Thread.sleep(rand.nextInt(100));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	public class CounterPoolExecutor extends ThreadPoolExecutor{
		private AtomicInteger count =new AtomicInteger(0);
		public long startTime=0;
		public String funcname="";
		public CounterPoolExecutor(int corePoolSize, int maximumPoolSize,
				long keepAliveTime, TimeUnit unit,
				BlockingQueue<Runnable> workQueue) {
			super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
		}
		
		protected void afterExecute(Runnable r, Throwable t) { 
			int l=count.addAndGet(1);
			if(l==TASK_COUNT){
				System.out.println(funcname+" spend time:"+(System.currentTimeMillis()-startTime));
			}
		}
	}
	
	public Object handleSet(int index){
		set.add(rand.nextInt(2000));
		if(set.size()>10000)set.clear();
		return null;
	}
	
	public void initSet(){
		set=Collections.synchronizedSet(new HashSet());

	}
	
	public void initFreeLockSet(){
		set=new LockFreeSet();

	}
	
	//@Test
	public void testSet() throws InterruptedException {
		initSet();
		CounterPoolExecutor exe=new CounterPoolExecutor(MAX_THREADS, MAX_THREADS,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>());

		long starttime=System.currentTimeMillis();
		exe.startTime=starttime;
		exe.funcname="testSet";
		for(int i=0;i<TASK_COUNT;i++)
			exe.submit(new AccessSetThread());
		
		Thread.sleep(10000);
	}
	
	@Test
	public void testLockFreeSet() throws InterruptedException {
		initFreeLockSet();
		CounterPoolExecutor exe=new CounterPoolExecutor(MAX_THREADS, MAX_THREADS,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>());

		long starttime=System.currentTimeMillis();
		exe.startTime=starttime;
		exe.funcname="testLockFreeSet";
		for(int i=0;i<TASK_COUNT;i++)
			exe.submit(new AccessSetThread());
		
		Thread.sleep(10000);
	}
}

由测试结果来看,在高并发的情况下,Amino提供的List性能要远超出JDK内置的基于锁的List性能要高出六七倍;

在高并发环境下,使用无锁的集合可以有效的提升系统的吞吐量。通过Amino框架,可以让开发人员轻松使用这种技术;

======================================================================

Amino CBB (Concurrent Building Blocks) 类库将提供优化后的并发线程组件,适用于JDK6.0 及其以后的版本。

Amino Java 类库将涉及下面四个方面的内容:

1) 数据结构 
该组件将提供一套免锁的集合类。因为这些数据结构采用免锁的运算法则来生成,所
以,它们将拥有基本的免锁组件的特性,如可以避免不同类型的死锁,不同类型的线程初始
化顺序等。 
2) 并行模式 
Amino 将为应用程序提供一个或几个大家熟知的并行计算模式。采用这些并行模式可
以使开发者起到事半功倍的效果,这些模式包括 Master-Worker、Map-reduce、Divide and 
conquer, Pipeline 等,线程调度程序可以与这些模式类协同工作,提供了开发效率。 
3) 并行计算中的一般功能 
Amino 将为应用程序提供并行计算中常用的方法,例如: 
a. String、Sequence  和Array  的处理方面。如Sort、Search、Merge、Rank、Compare、
Reverse、 Shuffle、Rotate 和Median 等 
4)原子和STM(软件事务内存模型) 

--------------------------------
在Amino 类库中,主要算法将使用锁无关的(Lock-Free)的数据结构。 

原语Compare-and-swap(CAS)  是实现锁无关数据结构的通用原语。CAS  可以原子
地比较一个内存位置的内容及一个期望值,如果两者相同,则用一个指定值取替这个内存位
罝里的内容,并且提供结果指示这个操作是否成功。

CAS 操作过程是:当处理器要更新一个内存位置的值的时候,它首
先将目前内存位置的值与它所知道的修改前的值进行对比(要知道在多处理的时候,你要更
新的内存位置上的值有可能被其他处理更新过,而你全然不知),如果内存位置目前的值与
期望的原值相同(说明没有被其他处理更新过),那么就将新的值写入内存位置;而如果不
同(说明有其他处理在我不知情的情况下改过这的值咯),那么就什么也不做,不写入新的
值(现在最新的做法是定义内存值的版本号,根据版本号的改变来判断内存值是否被修改,
一般情况下,比较内存值的做法已经满足要求了)。CAS 的价值所在就在于它是在硬件级别
实现的,速度那是相当的快。
————————————————下面提供多份测试代码——————————————

import java.util.Collection;
import java.util.List;
import java.util.Vector;

import org.amino.pattern.internal.Doable;
import org.amino.pattern.internal.DynamicWorker;
import org.amino.pattern.internal.MasterWorker;
import org.amino.pattern.internal.MasterWorkerFactory;
import org.amino.pattern.internal.WorkQueue;
import org.junit.Test;

public class TestMasterWorker {

	public class Pow3 implements Doable<Integer,Integer>{
		@Override
		public Integer run(Integer input) {

			return input*input*input;
		}
	}
	
	public class Pow3Dyn implements DynamicWorker<Integer,Integer>{
		@Override
		public Integer run(Integer w, WorkQueue<Integer> wq) {
			return w*w*w;
		}
	}
	
	@Test
	public void testStatic() {
		MasterWorker<Integer,Integer> mw=MasterWorkerFactory.newStatic(new Pow3());
		List<MasterWorker.ResultKey> keyList=new Vector<MasterWorker.ResultKey>();
		for(int i=0;i<100;i++){
			keyList.add(mw.submit(i));
		}
		mw.execute();
		int re=0;
		while(keyList.size()>0){					//不等待全部执行完成,就开始求和
			MasterWorker.ResultKey k=keyList.get(0);
			Integer i=mw.result(k);
			if(i!=null){
				re+=i;
				keyList.remove(0);
			}
		}
		System.out.println(re);
	}
	
	@Test
	public void testDynamic() {
		MasterWorker<Integer,Integer> mw=MasterWorkerFactory.newDynamic(new Pow3Dyn());
		List<MasterWorker.ResultKey> keyList=new Vector<MasterWorker.ResultKey>();
		for(int i=0;i<50;i++)
			keyList.add(mw.submit(i));
		mw.execute();								//在已经开始执行的情况下,继续添加任务
		for(int i=50;i<100;i++)
			keyList.add(mw.submit(i));
		int re=0;
		while(keyList.size()>0){					//不等待全部执行完成,就开始求和
			MasterWorker.ResultKey k=keyList.get(0);
			Integer i=mw.result(k);
			if(i!=null){
				re+=i;
				keyList.remove(0);
			}
		}
		System.out.println(re);
	}

	
}

===========================测试Dictionary===================================


import java.util.HashMap;
import java.util.Set;
import java.util.TreeMap;

import org.amino.ds.lockfree.LockFreeDictionary;
import org.junit.Test;

public class TestLockFreeDictionaryDemo {
	@Test
	public void test(){
		LockFreeDictionary<Integer ,Object> map=new LockFreeDictionary<Integer ,Object>();
		for(int i=0;i<100;i++)
			map.put(i, i);
		Set<Integer> keys=map.keySet();
		for(Integer i:keys)
			System.out.println(i);
		
	}
	
	@Test
	public void testTreeMap(){
		TreeMap<Integer ,Object> map=new TreeMap<Integer ,Object>();
		for(int i=0;i<100;i++)
			map.put(i, i);
		Set<Integer> keys=map.keySet();
		for(Integer i:keys)
			System.out.println(i);
	}
	
	//@Test
	public void testHashMap(){
		HashMap<Integer ,Object> map=new HashMap<Integer ,Object>();
		for(int i=0;i<100;i++)
			map.put(i, i);
		Set<Integer> keys=map.keySet();
		for(Integer i:keys)
			System.out.println(i);
	}
}

=================================测试Map====================================

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import org.amino.ds.lockfree.LockFreeDictionary;
import org.junit.Test;

public class TestLockFreeMap {
	private static final int MAX_THREADS = 20;
	private static final int TASK_COUNT = 40;
	java.util.Random rand=new java.util.Random();
	
	private static Object DUMMY=new Object();
	Map map;
	
	public class AccessMapThread implements Runnable{
		protected String name;
		
		public AccessMapThread(){
		}
		public AccessMapThread(String name){
			this.name=name;
		}
		@Override
		public void run() {
			try {
				for(int i=0;i<50000;i++)
					handleMap(rand.nextInt(1000));
				Thread.sleep(rand.nextInt(100));
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	public class CounterPoolExecutor extends ThreadPoolExecutor{
		private AtomicInteger count =new AtomicInteger(0);
		public long startTime=0;
		public String funcname="";
		public CounterPoolExecutor(int corePoolSize, int maximumPoolSize,
				long keepAliveTime, TimeUnit unit,
				BlockingQueue<Runnable> workQueue) {
			super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
		}
		
		protected void afterExecute(Runnable r, Throwable t) { 
			int l=count.addAndGet(1);
			if(l==TASK_COUNT){
				System.out.println(funcname+" spend time:"+(System.currentTimeMillis()-startTime));
				
			}
		}
	}
	
	public Object handleMap(int index){
		map.put(rand.nextInt(2000), DUMMY);
		return map.get(index);
	}
	
	public void initLockFreeMap(){
		map=new LockFreeDictionary();
		for(int i=0;i<1000;i++)
			map.put(i, DUMMY);
	}
	
	public void initTreeMap(){
		map=Collections.synchronizedMap(new TreeMap());
		for(int i=0;i<1000;i++)
			map.put(i, DUMMY);
	}
	
	
	@Test
	public void testLockFreeMap() throws InterruptedException {
		initLockFreeMap();
		CounterPoolExecutor exe=new CounterPoolExecutor(MAX_THREADS, MAX_THREADS,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>());

		long starttime=System.currentTimeMillis();
		exe.startTime=starttime;
		exe.funcname="testLockFreeMap";
		Runnable r=new AccessMapThread();
		for(int i=0;i<TASK_COUNT;i++)
			exe.submit(r);
		
		Thread.sleep(10000);
	}
	

	//@Test
	public void testTreeMap() throws InterruptedException {
		initTreeMap();
		CounterPoolExecutor exe=new CounterPoolExecutor(MAX_THREADS, MAX_THREADS,
                0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<Runnable>());

		long starttime=System.currentTimeMillis();
		exe.startTime=starttime;
		exe.funcname="testTreeMap";
		Runnable r=new AccessMapThread();
		for(int i=0;i<TASK_COUNT;i++)
			exe.submit(r);
		
		Thread.sleep(10000);
	}
}

======================================================================


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/617125.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

java设计模式之:建造者模式

文章目录 建造者模式介绍建造者模式适用场景案例场景一坨坨代码实现重构代码 与工厂模式区别建造者模式优缺点总结 该说不说几乎是程序员都知道或者了解设计模式&#xff0c;但大部分小伙伴写代码总是习惯于一把梭。好的代码不只为了完成现有功能&#xff0c;也会考虑后续扩展。…

springboot自动配置源码解析

概述 使用springboog的时候引入starter就自动为我们加载&#xff0c;例如我们引入 spring-boot-starter-web 之后&#xff0c;就自动引入了 Spring MVC 相关的 jar 包&#xff0c;从而自动配置 Spring MVC 。 自动装配原理 SpringBootApplication SpringBootApplication: Spri…

Java的引用

一、概述 其实java有4种引用&#xff0c;4种可分为强、软、弱、虚。我们将从这四个方面入手进行介绍。 二、强引用 首先看到我们有一个类叫M&#xff0c;在这个类里我重写了一个方法叫finalize()&#xff0c;我们可以看到这个方法是已经被废弃的方法&#xff0c;为什么要重写…

【jupyter】Jupyter Notebook如何导入导出文件

目录 0.系统&#xff1a;windows 1.打开 Jupyter Notebook 2.Jupyter Notebook导入文件 3.Jupyter Notebook导出文件 0.系统&#xff1a;windows 1.打开 Jupyter Notebook 1&#xff09;下载【Anaconda】后&#xff0c;直接点击【Jupyter Notebook】即可在网页打开 Jupyte…

用户研究干货——这一篇就够啦

一、基本概念&#xff1a; ①工作内容&#xff1a;用户研究的首要目的是帮助企业定义产品目标用户群&#xff0c;明确、细化产品概念&#xff0c;并通过对用户的任务操作特性、知觉特征、认知心理特征的研究&#xff0c;使用户的实际需求成为产品设计的导向&#xff0c;使产品…

建面超72万㎡,南山红花岭旧改规划公示,配套近15万㎡宿舍

近日&#xff0c;深圳市南山区城市更新和土地整备局发布关于桃源街道红花岭工业南区更新单元&#xff08;暂定名&#xff09;03-01、02-02地块《建设工程规划许可证》及总平面图的公告。 此次批复的红花岭工业南区02-02、03-01块&#xff0c;总建面超72万㎡&#xff0c;用地单…

nginx+tomcat 负载均衡、动静分离集群

文章目录 一、NginxTomcat负载均衡的组合原因1.1 Nginx实现负载均衡的原理1.2 Nginx实现负载均衡的主要配置项1.3 NginxTomcat负载均衡的组合的优点1.4 NginxTomcat负载均衡的实验设计 二、动静分离部署2.1 部署TOMCAT后端服务器2.2部署nginx服务器2.3安装nginx动态服务器 一、…

java中try-with-resources自动关闭io流

在传统的输入输出流处理中&#xff0c;我们一般使用的结构如下所示&#xff0c;使用try - catch - finally结构捕获相关异常&#xff0c;最后不管是否有异常&#xff0c;我们都将流进行关闭处理&#xff1a; try {//todo } catch (IOException e) {log.error("read xxx f…

《Lua程序设计》--学习1

前言&#xff1a; --> 表示一条语句的输出或表达式求值的结果 -- 单行注释 > 标注 一些代码需要在交互模式下输入 如果需要打印表达式求值的结果&#xff0c;必须在每个表达式前加上一个等号 <--> 表示两者完全等价 语言基础 我们将Lua语言执行的每一…

html选择器

基本选择器 基本选择器 : 标签选择器 , 类选择器 , ID选择器 标签选择器 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEed…

小企业软件项目流程六步法

小企业软件项目流程六步法&#xff0c;很有效 软件项目的沟通成本是巨大的 软件生产是非常特殊的一套流程 没有过程控制&#xff0c;最终一定失控或废弃 趣讲大白话&#xff1a;输入垃圾&#xff0c;输出也是垃圾 【趣讲信息科技188期】 **************************** 软件行业…

九、(补充文章四)Arcgis实现深度学习训练样本数据的批量制作——只靠原图+shp如何批量制作样本图片

之前写了一些个深度学习系列文 其中先是单张样本的制作方法 最后通过构造模型批量处理 大大提高了生成样本的速度 四、Arcgis实现深度学习河流训练样本数据的制作(使用软件批量获取样本图片)——对已经获取到的完整面状样本数据进行处理 但是这个方法不仅仅需要shp和原图 还需要…

在不到200行的HTML代码中,实现老板要求为他的孩子绘制一个童话乐园:七彩彩虹、微笑笑脸和魔法树

文章目录 准备工作1.绘制七彩彩虹2.绘制微笑笑脸3.绘制多变的魔法树 结语 欢迎来到童话乐园&#xff01;这里有一些有趣的绘图功能&#xff0c;让你在代码的世界中感受童话般的乐趣。本篇博文将介绍如何使用代码来绘制七彩彩虹、微笑笑脸和魔法树。让我们一起来探索吧&#xff…

vector 练习

目录 一、创建动态二维数组的方法 0x01 C语言法 0x02 C法 二、 杨辉三角 三、电话号码的数字组合 一、创建动态二维数组的方法 0x01 C语言法 int** p (int**)malloc(sizeof(int*) * M);//创建M行的数组,每一行都是一个数组 for(size_t i 0;i < M;i) {p[i] (int*)mal…

Redis主从集群与哨兵集群

一、Redis 哨兵集群原理 Redis 哨兵集群是一种高可用性的解决方案&#xff0c;用于监控 Redis 实例的状态并在实例出现故障时自动进行故障转移。 Redis 哨兵集群由多个哨兵实例组成&#xff0c;每个哨兵实例都运行在独立的服务器上。每个哨兵实例都会周期性地向 Redis 实例发…

Linux内存初始化-启动阶段的内存初始化

本文代码基于ARM64平台, Linux kernel 5.15 在加载kernel 之前&#xff0c; kernel对于系统是有一定要求的&#xff0c;明确规定了boot阶段必须要把MMU关闭&#xff1a; arch/arm64/kernel/head.S/** Kernel startup entry point.* ---------------------------** The require…

路径规划算法:基于松鼠优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于松鼠优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于松鼠优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法松鼠…

入门大数据就业前景怎么样?

时势造英雄&#xff0c;对个人而言亦是如此。跟随趋势&#xff0c;找准自己未来发力的赛道&#xff0c;在合适的时间干合适的事&#xff0c;就是抓住自己的未来。 猎聘大数据研究院发布了《2022未来人才就业趋势报告》 从排名来看&#xff0c;2022年1-4月各行业中高端人才平均…

mac m1/m2 安装 ps 2023 插件无法显示扩展界面

碎碎念&#xff1a;一直在踩坑的路上&#xff0c;甚至想休息时间玩一会儿 ps 都能踩坑 问题描述 新的 m2 芯片 mac 安装了色环插件后&#xff0c;在窗口界面中没有找到扩展&#xff0c;且在首选项->增效工具的旧版扩展也是灰色的 题外话&#xff1a;记录一下 mac 的 photo…

2023尚上优选-社区团购 优选电商Spring Cloud Alibaba

尚上优选2023最新企业级微服务架构项目 分布式微服务后端VUE、小程序 尚上优选是真实居住社区内居民团体的一种互联网线上线下购物消费行为&#xff0c;是依托真实社区的一种区域化、小众化、本地化、网络化的团购形式。简而言之&#xff0c;它是依托社区和团长社交关系实现生…