该帖已经被评为良好帖
|
|
---|---|
作者 | 正文 |
发表时间:2010-07-13
int len=list.size()/threadCounts;//平均分割List
for(int i=0;i<threadCounts;i++){ //创建线程任务 exec.execute(new SubIntegerSumTask(list.subList(i*len, len*(i+1)))); } 这个好像不能将所有的list全部运行完吧 如果int len=list.size()/threadCounts不能整除是个近似数的话 就有问题了 |
|
返回顶楼 | |
发表时间:2010-07-13
hrsvici412 写道 学到好多线程的东西,请问 你的分析的图,是用什么工具画的!
好像是office2007or2010 里面有一个好像就叫流程图的东西~ |
|
返回顶楼 | |
发表时间:2010-07-13
<code>
ExecutorService exec=Executors.newFixedThreadPool(threadCounts); int len=list.size()/threadCounts;//平均分割List for(int i=0;i<threadCounts;i++){ //创建线程任务 exec.execute(new SubIntegerSumTask(list.subList(i*len, len*(i+1)))); } </code> 这段是不是有点问题, int len=list.size()/threadCounts你确保正好整除吗? |
|
返回顶楼 | |
发表时间:2010-07-13
另外,个人感觉这里用CountDownLatch比用CyclicBarrier更合适点,这个案例只需要主线程等待子线程,各子线程间不需要相互等待,子线程求和完成后可以立即输出并结束。
|
|
返回顶楼 | |
发表时间:2010-07-13
xifo 写道 思路是对的,可惜算法有问题,大多数情况下计算结果不正确。
不信的话,试试把这一行 for (int i = 1; i <= 1000000; i++) 换成 for (int i = 0; i <= 1000000; i++) 如果计算正确,两个计算结果应该一样,实际上计算结果会少一百万,原因是分割那里没有考虑尾数。 你好细心哦,这都被你看出来了,确实,在分割的时候,分割的最后一组应该考虑一下不能整除情况下的余数,呵呵 |
|
返回顶楼 | |
发表时间:2010-07-13
最后修改:2010-07-13
以前写过类似这样的东西 但是没有CyclicBarrier类
ExecutorService 的 shutdown 方法应该在 barrier.await(); 前面 你的内部类实现 callable 接口 然后Call 会返回值 ExecutorService 的submit方法可以返回一个 Future 对象 Future 对象来实现同步很好用的 可以尝试下 用 Futrue 的 isDone 来判断线程是否工作结束 |
|
返回顶楼 | |
发表时间:2010-07-13
个人也觉得使用CountDownLatch就可以了. 还有, 包含所有整数的List没必要拆分为一个个小的List, 只要算出各自计算的index范围, 第一计算1-100个, 第二个计算101-200个, 从同一个List中取值.
|
|
返回顶楼 | |
发表时间:2010-07-13
顶,今天才知道了CyclicBarrier这个类。学习。。
看大家都这样说,楼主的分割好像有问题。 |
|
返回顶楼 | |
发表时间:2010-07-13
最后修改:2010-07-13
飞雪无情 写道 引用 本文主要通过一个淘宝的面试题为引子,介绍了并发的一点小知识,主要是介绍通过CyclicBarrier同步辅助器辅助多个并发任务共同完成一件工作。Java SE5的java.util.concurrent引入了大量的设计来解决并发问题,使用它们有助于我们编写更加简单而健壮的并发程序。 不用这么麻烦吧 用ExecutorService.invokeAll就行了吧。 嗯。。使用ExecutorService.invokeAll可以,不用认为的控制同步及其等待。但是使用CyclicBarrier有它的好处,关键就是方便灵活,可以控制什么时候进行等待。下面是使用ExecutorService.invokeAll实现的方法,运行结果是一样的: /** * 使用ExecutorService的invokeAll方法计算 * @author 飞雪无情 * */ public class CountSumWithCallable { /** * @param args * @throws InterruptedException * @throws ExecutionException */ public static void main(String[] args) throws InterruptedException, ExecutionException { int threadCounts =20;//使用的线程数 long sum=0; ExecutorService exec=Executors.newFixedThreadPool(threadCounts); List<Callable<Long>> callList=new ArrayList<Callable<Long>>(); //生成很大的List List<Integer> list = new ArrayList<Integer>(); for (int i = 1; i <= 1000000; i++) { list.add(i); } int len=list.size()/threadCounts;//平均分割List //List中的数量没有线程数多(很少存在) if(len==0){ threadCounts=list.size();//采用一个线程处理List中的一个元素 len=list.size()/threadCounts;//重新平均分割List } for(int i=0;i<threadCounts;i++){ final List<Integer> subList; if(i==threadCounts-1){ subList=list.subList(i*len,list.size()); }else{ subList=list.subList(i*len, len*(i+1)>list.size()?list.size():len*(i+1)); } //采用匿名内部类实现 callList.add(new Callable<Long>(){ public Long call() throws Exception { long subSum=0L; for(Integer i:subList){ subSum+=i; } System.out.println("分配给线程:"+Thread.currentThread().getName()+"那一部分List的整数和为:\tSubSum:"+subSum); return subSum; } }); } List<Future<Long>> futureList=exec.invokeAll(callList); for(Future<Long> future:futureList){ sum+=future.get(); } exec.shutdown(); System.out.println(sum); } } |
|
返回顶楼 | |
发表时间:2010-07-13
很好的列子,后面大家补充的算法漏洞也很精彩
|
|
返回顶楼 | |