博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并行搜索
阅读量:4960 次
发布时间:2019-06-12

本文共 2870 字,大约阅读时间需要 9 分钟。

  搜索是几乎每一个软件都必不可少的功能。对于有序数据,通常采用二分查找法。对于无序数据,则只能挨个查找。

  给定一个数组,我们要查找满足条件的元素。对于串行程序来说,只要遍历一下数组就可以得到结果。但是如果要使用并行方式,则需要额外增加一些线程间的通信机制,使各个线程可以有效的运行。

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

  假设有一个整数数组,我们需要查找数组内的元素:

1 public class CurrentSearch { 2     static int[] arr = {3,2,32,323123,435,45,768,79,67,789,8098,0};//定义整型数组 3     static ExecutorService pool = Executors.newCachedThreadPool(); 4     static final int Thread_Num = 2; 5     static AtomicInteger result = new AtomicInteger(-1);//定义存放结果的变量,-1表示没有找到给定元素。 6  7     /** 8      * 并发搜索会要求每个线程查找arr中的一段,因此搜索方法必须指定线程需要搜索的开始位置和结束位置 9      */10     public static int search(int searchValue,int beginPos,int endPos){11         int i = 0;12         for (i = beginPos;i < endPos;i++){13             if (result.get() >= 0){
//判断是否已经有其他线程搜索到了需要的结果14 return result.get();15 }16 if (arr[i] == searchValue){17 //如果设置失败,表明其他线程已经先找到了18 if (!result.compareAndSet(-1,i)){
//使用CAS操作,可以无视失败的情况19 return result.get();20 }21 return i;22 }23 }24 return -1;25 }26 //定义一个线程查找,调用前面的search()方法27 public static class SearchTask implements Callable
{28 29 int begin,end,searchValue;30 31 public SearchTask(int searchValue,int begin,int end){32 this.begin = begin;33 this.end = end;34 this.searchValue = searchValue;35 }36 @Override37 public Integer call() throws Exception {38 int re = search(searchValue,begin,end);39 return re;40 }41 }42 //根据线程数量进行划分,并建立对应的任务提交给线程池处理43 public static int pSearch(int searchValue) throws ExecutionException, InterruptedException {44 int subArrSize = arr.length/Thread_Num+1;45 List
> re = new ArrayList
>();46 for (int i = 0;i < arr.length;i += subArrSize){47 int end = i + subArrSize;48 if (end >= arr.length){49 end = arr.length;50 }51 re.add(pool.submit(new SearchTask(searchValue,i,end)));52 }53 for (Future
future: re){54 if (future.get() >= 0){55 return future.get();56 }57 }58 return -1;59 }60 //测试61 public static void main(String[] args) throws ExecutionException, InterruptedException {62 int value = pSearch(0);63 System.out.println(value);64 }65 }

 上述代码使用了Future模式,其中第46到52行,将原始数组划分成若干份,并根据每段结果建立子任务(每段分配一个线程),每一个子任务都会返回一个Future对象,通过Future对象可以获得线程组得到的最终结果,在这个例子中,我们通过result共享彼此的信息,因此只要当一个线程成功返回后,其他线程就会立即返回(代码第18到20行)。因此,不会出现由于排在前面的任务长时间无法结束而导致整个搜索结果无法立即获取的情况。

参考:《Java高并发程序设计》 葛一鸣 郭超 编著:

转载于:https://www.cnblogs.com/Joe-Go/p/9817466.html

你可能感兴趣的文章
highcharts曲线图
查看>>
extjs动态改变样式
查看>>
PL/SQL Developer 查询的数据有乱码或者where 字段名=字段值 查不出来数据
查看>>
宏定义
查看>>
ubuntu12.04 串口登录系统配置
查看>>
poj3061
查看>>
linux--多进程进行文件拷贝
查看>>
笔记:git基本操作
查看>>
Gold Smith第一章
查看>>
生成php所需要的APNS Service pem证书的步骤
查看>>
JavaWeb之JSON
查看>>
URL中的特殊字符处理
查看>>
HOT SUMMER 每天都是不一样,积极的去感受生活 C#关闭IE相应的窗口 .
查看>>
windows平台上编译mongdb-cxx-driver
查看>>
optionMenu-普通菜单使用
查看>>
MVC3分页传2参
查看>>
2016-2017-2点集拓扑作业[本科生上课时]讲解视频
查看>>
appium(13)- server config
查看>>
IIS负载均衡-Application Request Route详解第六篇:使用失败请求跟踪规则来诊断ARR...
查看>>
管理信息系统 第三部分 作业
查看>>