博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
多线程排序
阅读量:5101 次
发布时间:2019-06-13

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

import java.util.*; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class SortMain {
public static void main(String[] args) throws Exception{
Integer threadNumber = 4; //线程数量 Integer stopNumber = threadNumber; //闭合器数量 Integer randomCount = 50; //随机数数量 Integer randomNumber = 50; //随机数范围 List
workSpeace = new ArrayList<>(); //每个线程需要工作的量 list的长度与线程量一样 if(randomCount % threadNumber == 0){
for(int i=0; i < threadNumber; i ++){
workSpeace.add(randomCount/threadNumber); } }else{
Integer itemValue = randomCount/threadNumber; for(int i = 0 ; i < threadNumber ; i ++){
if(i == threadNumber -1){
workSpeace.add((randomCount-(itemValue*threadNumber)) + itemValue); }else{
workSpeace.add(itemValue); } } } CountDownLatch countDownLatch = new CountDownLatch(stopNumber); //闭合器子线程闭合器 CountDownLatch countDownLatchMain = new CountDownLatch(stopNumber); //主线程闭合器 ExecutorService executors = Executors.newFixedThreadPool(threadNumber); //线程池 Lock lock = new ReentrantLock(); List
arrayList = new ArrayList<>(); Random random = new Random(System.currentTimeMillis()); try {
for(int i=0; i < randomCount ; i++){
arrayList.add(random.nextInt(randomNumber)); } System.out.println("随机数集合:"+arrayList +" 长度:"+arrayList.size()); Map
thradValueMap = Collections.synchronizedMap(new HashMap()); Map
> mainValueMap = Collections.synchronizedMap(new HashMap()); List countSizeListValue = new ArrayList(); // for(int i =0; i
paramsList = new ArrayList(); //每个线程工作的内容 //思路:每个线程干10个值,10个线程干100个值 int startIndex; //没个线程工作的10个值的尾坐标,也是没个线程管理数值的结束 //startIndex endThreadIndex 因为for循环是反着的,所以这个值也是反着的 int endThreadIndex; //没个线程工作的10个值的头坐标,也是没个线程管理数值的开始 endThreadIndex = ((randomCount/threadNumber)*finalI); if(finalI == threadNumber-1){
startIndex = ((randomCount - ((randomCount/threadNumber)*finalI)) + endThreadIndex) -1; }else{
startIndex = endThreadIndex + ((randomCount/threadNumber)-1); } for(int forStartIndex = startIndex; forStartIndex >= endThreadIndex; forStartIndex--){
paramsList.add(arrayList.get(forStartIndex)); //通过循环拿到每个线程需要工作的内容 } //由于已知随机数最大的值是100,所以可以很容易的规范没个线程所管理的值范围,在这里暂定 1号线程工作范围为0-10.2号线程为11-20,以此类推 //start 此代码块规定此线程管理值的区间 int theManageValueMax; int theManageValueMin; if(finalI == threadNumber-1){//9 theManageValueMax = startIndex+1; theManageValueMin = endThreadIndex; }else{
theManageValueMax = startIndex; theManageValueMin = endThreadIndex; } List
discardValue = new ArrayList<>(); //需要剔除的值的集合 for(int chickIndex = 0; chickIndex < workSpeace.get(finalI); chickIndex++){ //循环判断每个线程需要工作内容值 Integer workValue = paramsList.get(chickIndex); //每个线程工作的基本单位(数值) if(theManageValueMin <= workValue&&workValue <= theManageValueMax){ //如果符合工作数值区间,则什么都不做; continue; }else{ //如果不符合工作区间,则剔除到公共区域 Integer thisNumberParent = -1; try { lock.lockInterruptibly(); thisNumberParent = chickNumberParent(threadNumber, randomNumber, workValue); //调用此方法判断此随机数属于哪个线程的工作区间 }catch (Exception e){ for(StackTraceElement itemError : e.getStackTrace()){ System.out.println(itemError); } }finally { lock.unlock(); } String theValueByMap = thradValueMap.get(thisNumberParent); if(theValueByMap == null || "".equals(theValueByMap)){ thradValueMap.put(thisNumberParent,workValue.toString()); }else{ thradValueMap.put(thisNumberParent,theValueByMap + ","+workValue.toString()); } discardValue.add(workValue); } } for(Integer itemDiscardvalue :discardValue){ paramsList.remove(new Integer(itemDiscardvalue.intValue())); } countDownLatch.countDown(); try { countDownLatch.await(); String thisThreadWorkValue = thradValueMap.get(finalI); //当所有子线程工作完之后 从公共区域拿出本应该属于自己的值 if(thisThreadWorkValue == null || "".equals(thisThreadWorkValue)){ //如果公共区域没有属于自己的工作值 }else { String thisThreadWorkValueSz[] = thisThreadWorkValue.split(","); for(int i=0; i < thisThreadWorkValueSz.length; i++){ paramsList.add(Integer.valueOf(thisThreadWorkValueSz[i])); } paramsList = sortInt(paramsList); } mainValueMap.put(finalI,paramsList); }catch (Exception e){ e.fillInStackTrace(); }finally { countDownLatchMain.countDown(); } // System.out.println("分割线---------------------------------"); } }); } countDownLatchMain.await(); List
finalList = new ArrayList<>(); for(int i =0; i
itemList = mainValueMap.get(i); if(itemList == null || itemList.isEmpty()){ continue; } for(Integer itemValue : itemList){ finalList.add(itemValue); } } System.out.println("排序好的值:"+finalList+" 长度:"+finalList.size()); arrayList.removeAll(finalList); System.out.println("差集为:"+arrayList); }catch (Exception e){ for(StackTraceElement itemError :e.getStackTrace()){ System.out.println(itemError); } }finally { executors.shutdownNow(); } } /** * * @param paramsList 每个线程要干的事情...排序 * @return */ private static List
sortInt(List
paramsList){ List
resutList = new LinkedList<>(); for(int paramsListIndex = 0 ; paramsListIndex
= 0 ; resultListIndex--){ if(resultListIndex == 0){ resutList.add(resultListIndex,paramsList.get(paramsListIndex)); break; } int paramsListInt = paramsList.get(paramsListIndex).intValue(); int resultListInt = resutList.get(resultListIndex-1).intValue(); if(paramsListInt <= resultListInt){ continue; }else{ resutList.add(resultListIndex,paramsList.get(paramsListIndex)); break; } } } return resutList; } /** * 判断该数值在map中的key应该是多少 * @param threadNumber 线程量 * @param randomNumber 随机数范围 * @param needChickNumber 需要判断的值 * @return */ private static Integer chickNumberParent(Integer threadNumber,Integer randomNumber,Integer needChickNumber){ Integer onlyThreadNumber = randomNumber/threadNumber; //单个线程负责值得区间, 比如 93个随机数 6个线程, 那么93/6 就是前五个的线程负责量,余数是最后一个线程负责量 Integer valueIndex = needChickNumber / onlyThreadNumber; //还以上一行注释为例子, 如果现在需要判断93这个值属于哪个线程的工作区间,则 93/(随机数数量/线程量) 93/15 = 6, 因为线程量一共为6,在list中长度最大值为5(因为list坐标从0开始),所以93这个值属于最后一个线程的工作区间 if(valueIndex >= threadNumber){ return valueIndex-1; }else{ return valueIndex; } } }

转载于:https://www.cnblogs.com/llja/p/10620335.html

你可能感兴趣的文章
【实例】原生 js 实现全屏滚动效果
查看>>
atitit.java解析sql语言解析器解释器的实现
查看>>
Ubuntu18.04安装
查看>>
struts2文件下载及文件名中文问题
查看>>
使用原生Java代码生成可执行Jar包
查看>>
<轉>APUE:mmap函数
查看>>
网站结构优化
查看>>
IFrame与window对象(contentWindow)
查看>>
19、Flask实战第19天:CSRF攻击与防御
查看>>
Shell Notes(2)
查看>>
ArcGIS Engine开发前基础知识(3)
查看>>
阮老师谈虚数
查看>>
Android Support兼容包详解
查看>>
Socket通信案例
查看>>
2015/7/24 (等待回调,结果是盘中回调,盘末拉升,错过了进仓机会吗?详情进入...
查看>>
Delphi XE7的安卓程序如何调用JAVA的JAR,使用JAVA的类?
查看>>
对 NGUI 子节点的位置的一点理解
查看>>
[LeetCode] Search in Rotated Sorted Array [35]
查看>>
仙剑---相爱
查看>>
UNIX网络编程卷1 时间获取程序server UDP 协议无关
查看>>