对无序数组的并发搜索的实现可以充分的用到多cpu的优势

一种简单的策略是将原始数组按照期望的线程数进行分割,如果我们计划使用两个线程进行搜索,就可以把一个数组分成两个,每个线程各自独立的搜索,当其中有一个线程找到数据后,立即返回结果的index即可。

首先index需要采用atomicinteger来进行修饰,默认初始化的值为-1,意义为当前未找到,由于内部采用CAS机制,线程在遍历比较是否相等之前,会通过atomicinteger中的get方法拿到当前的值,如果大于等于0,那么说明别的线程已经找到了结果,直接返回get值就可以。如果比较的过程中发现相等了,那么调用atomicinteger中的compareAndSet(-1,i),如果方法返回成功,则说明当前的线程是第一个发现结果的,那么返回当前index即可,如果失败,则说明别的线程先获得了结果,直接返回atomicinteger中的get方法获取的值即可。

整个过程采用future实现,拿到了Future后,不断地轮询结果,如果大于0即返回结果。

具体实现:

package parallel;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger; public class SeatchTask implements Callable<Integer>{
static int[] arr = {2,34,5,6};
static ExecutorService pool = Executors.newCachedThreadPool();
static final int Thread_Num = 2;
static AtomicInteger result = new AtomicInteger(-1);
int begin,end,searchValue;
public static int search(int searchValue, int beginPos, int endPos){
int i = 0;
for(i = beginPos; i < endPos;i ++){
if(result.get() > 0){
return result.get();
}
if(arr[i] == searchValue){
if(!result.compareAndSet(-1, i)){
return result.get();
}
return i;
}
}
return -1;
}
@Override
public Integer call() throws Exception {
int re = search(searchValue, begin, end);
return re;
}
public SeatchTask(int searchValue, int begin, int end){
this.searchValue = searchValue;
this.begin = begin;
this.end = end;
}
public static int pSearch(int searchValue) throws InterruptedException, ExecutionException{
int subArrSize = arr.length/Thread_Num + 1;
List<Future<Integer>> re = new ArrayList<Future<Integer>>();
for(int i = 0;i < arr.length;i +=subArrSize){
int end = i + subArrSize;
if(end <= arr.length) end = arr.length;
re.add(pool.submit(new SeatchTask(searchValue, i, end)));
}
for(Future<Integer> fu : re){
if(fu.get() >= 0){
return fu.get();
}
}
return -1;
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
int index = pSearch(34);
System.out.println(index);
}
}

对无序数组的并发搜索的java实现的更多相关文章

  1. java面向对象的有序数组和无序数组的比较

    package aa; class Array{ //定义一个有序数组 private long[] a; //定义数组长度 private int nElems; //构造函数初始化 public ...

  2. 快速查找无序数组中的第K大数?

    1.题目分析: 查找无序数组中的第K大数,直观感觉便是先排好序再找到下标为K-1的元素,时间复杂度O(NlgN).在此,我们想探索是否存在时间复杂度 < O(NlgN),而且近似等于O(N)的高 ...

  3. 无序数组a,求a[i]-a[j]的最大值,且i<j

    一道面试题:对于无序数组a,求a[i]-a[j]的最大值,其中i<j package test; import java.util.Arrays; public class FindMax { ...

  4. 细说并发5:Java 阻塞队列源码分析(下)

    上一篇 细说并发4:Java 阻塞队列源码分析(上) 我们了解了 ArrayBlockingQueue, LinkedBlockingQueue 和 PriorityBlockingQueue,这篇文 ...

  5. 《程序员代码面试指南》第八章 数组和矩阵问题 找到无序数组中最小的k 个数

    题目 找到无序数组中最小的k 个数 java代码 package com.lizhouwei.chapter8; /** * @Description: 找到无序数组中最小的k 个数 * @Autho ...

  6. 《深入了解java虚拟机》高效并发读书笔记——Java内存模型,线程,线程安全 与锁优化

    <深入了解java虚拟机>高效并发读书笔记--Java内存模型,线程,线程安全 与锁优化 本文主要参考<深入了解java虚拟机>高效并发章节 关于锁升级,偏向锁,轻量级锁参考& ...

  7. 有1,2,3一直到n的无序数组,排序

    题目:有1,2,3,..n 的无序整数数组,求排序算法.要求时间复杂度 O(n), 空间复杂度O(1). 分析:对于一般数组的排序显然 O(n) 是无法完成的. 既然题目这样要求,肯定原先的数组有一定 ...

  8. 探索 Java 同步机制[Monitor Object 并发模式在 Java 同步机制中的实现]

    探索 Java 同步机制[Monitor Object 并发模式在 Java 同步机制中的实现] https://www.ibm.com/developerworks/cn/java/j-lo-syn ...

  9. 【算法】数组与矩阵问题——找到无序数组中最小的k个数

    /** * 找到无序数组中最小的k个数 时间复杂度O(Nlogk) * 过程: * 1.一直维护一个有k个数的大根堆,这个堆代表目前选出来的k个最小的数 * 在堆里的k个元素中堆顶的元素是最小的k个数 ...

随机推荐

  1. centos上源码安装clang 3.8

    之前想在centos系统上安装clang 3.6版本,由于yum上版本太低,想通过源码编译安装.按照网上说的源码安装步骤,下好llvm.clang.clang-tools-extra和compiler ...

  2. 如何根据一些参数,自动生成一个简单的maven工程,然后导入Eclipse直接使用?(maven命令)

    1. 使用mvn archetype:generate命令 2. 选择archetype类型:(默认是org.apache.maven.archetypes:maven-archetype-quick ...

  3. nfs服务、crond服务

    一.nfs服务 NFS 是Network File System的缩写,即网络文件系统.一种使用于分散式文件系统的协定,由Sun公司开发,于1984年向外公布.功能是通过网络让不同的机器.不同的操作系 ...

  4. s5_day2作业

    # 1:编写for循环,利用索引遍历出每一个字符 # msg = 'hello egon 666' # for i in range(len(msg)): # print(i,msg[i]) # 2: ...

  5. 在Windows上以服务方式运行 Redis

    ServiceStack.Redis 使用教程里提到Redis最好还是部署到Linux下去,Windows只是用来 做开发环境,现在这个命题发生改变了,在Windows上也可以部署生产环境的Redis ...

  6. Linux Shell编程 exit、break、continue

    exit语句 在系统中exit 命令用于退出当前用户的登录状态.在 Shell 脚本中exit 语句是用来退出当前脚本. exit 的语法如下: exit [返回值] 如果在 exit 之后定义了返回 ...

  7. CF961G Partitions(第二类斯特林数)

    题目 CF961G 前置 斯特林数\(\Longrightarrow\)斯特林数及反演总结 做法 相信大家能得出一个一眼式:\[Ans=\sum\limits_{i=1}^n w_i\sum\limi ...

  8. 基于SSM的单点登陆04

    jdbc.properties JDBC_DRIVER=org.mariadb.jdbc.Driver JDBC_URL=jdbc:mariadb://127.0.0.1:3306/market JD ...

  9. Saltstack 命令行:批量发送命令,返回执行结果

    批量发送发送命令符,并返回结果. salt '*' cmd.run 'df -h' ---------------------------------------- Stest1: Filesyste ...

  10. log4j日志的配置--Debug

    ############################### 日志记录器定义 ################################ 日志输出级别 OFF.DEBUG.INFO.WARN. ...