- 浏览: 550789 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (344)
- ··············未分类············· (33)
- Eclipse 插件 (15)
- EDA 工具 (1)
- Linux/Unix (3)
- Java (43)
- Java Applet (1)
- Java Draw2d (22)
- Java Draw2d version2 (6)
- Java GEF (2)
- Java SWT (21)
- Java SWT Image 图像 (21)
- Java SWT Tree (16)
- Java SWT Table (4)
- Java SWT TableViewer (11)
- Java SWTbot (4)
- Java Test (2)
- Java Thread 多线程 (22)
- Java Zest (5)
- RC2_3S400学习笔记 (16)
- tcl 脚本 (10)
- Verilog (7)
- XML (6)
- 国家 (5)
- 感叹 (4)
- 面试题 (9)
- 生活 (36)
- 足球 世界杯 (8)
- 老公看你的 (3)
- web开发 (1)
- 数据结构——图 (7)
- c language (1)
最新评论
-
zxjlwt:
路过素人派http://surenpi.com
SWT 树的事件 SWT.Selection SWT.CHECK SWT.DefaultSelection -
hj01kkk:
1楼用法正解
JDK 7 中的 Fork/Join 模式 -
fish_no7:
使用 new SortTask().fork()
JDK 7 中的 Fork/Join 模式 -
wpf523:
mark
Java 多线程例子6 线程安全 线程同步 同步代码块 同步函数 -
uniquejava:
以前碰到过,估计是在icu包中实现了双击自动选中一段文本的功能 ...
java.lang.NoClassDefFoundError: com/ibm/icu/text/BreakIterator
利用多核CPU计算大的列表中的整数和 CyclicBarrier CountDownLatch ExecutorService
- 博客分类:
- Java Thread 多线程
原文:http://flysnow.iteye.com/blog/711162
原文利用了CyclicBarrier、ExecutorService和Callable技术,这些我还不是太懂。将原实现改了一下
public class CountListIntegerSum1 { private Long sum=0L;//存放整数的和 private List<Integer> list;//整数集合List private int threadCounts;//使用的线程数 public CountListIntegerSum1(List<Integer> list,int threadCounts) { this.list=list; this.threadCounts=threadCounts; } /** * 获取List中所有整数的和 */ public void getIntegerSum(){ int len=list.size()/threadCounts;//平均分割List if(len==0) { threadCounts=list.size();//采用一个线程处理List中的一个元素 len=list.size()/threadCounts;//重新平均分割List } int tmp = threadCounts; for(int i=0;i<tmp;i++) { if(i==tmp-1) {//最后一个线程承担剩下的所有元素的计算 new Thread(new SubIntegerSumTask(list.subList(i*len,list.size()))).start(); } else { new Thread(new SubIntegerSumTask(list.subList(i*len, len*(i+1)>list.size()?list.size():len*(i+1)))).start(); } } } /** * 分割计算List整数和的线程任务 * */ public class SubIntegerSumTask implements Runnable { private List<Integer> subList; public SubIntegerSumTask(List<Integer> subList) { this.subList=subList; } public void run() { long subSum=0L; for (Integer i : subList) { subSum += i; } synchronized(sum) { sum+=subSum; } System.out.println("分配给线程:"+Thread.currentThread().getName()+" 那一部分List的整数和为:"+subSum); if(--threadCounts == 0) { System.out.println("最后的结果为: ------- " + sum); } } } public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); int threadCounts = 10;//采用的线程数 //生成的List数据 for (int i = 1; i <= 1000000; i++) { list.add(i); } CountListIntegerSum1 countListIntegerSum=new CountListIntegerSum1(list,threadCounts); countListIntegerSum.getIntegerSum(); } }
分配给线程:Thread-8 那一部分List的整数和为:85000050000
分配给线程:Thread-2 那一部分List的整数和为:25000050000
分配给线程:Thread-1 那一部分List的整数和为:15000050000
分配给线程:Thread-6 那一部分List的整数和为:65000050000
分配给线程:Thread-3 那一部分List的整数和为:35000050000
分配给线程:Thread-5 那一部分List的整数和为:55000050000
分配给线程:Thread-0 那一部分List的整数和为:5000050000
分配给线程:Thread-9 那一部分List的整数和为:95000050000
分配给线程:Thread-7 那一部分List的整数和为:75000050000
最后的结果为: ------- 500000500000
当然结果还是一样的,这里当所有线程运行完打印出结果,即threadCounts为0时打印。这里还有一个小问题本以为是不是sublist = list.subList(2, 4);就会生成新的list,原来不会。
小提示:list.subList并没有产生新的list
sublist = list.subList(2, 4);这里的sublist 只是RandomAccessSubList,所以对list操作会影响sublist,对sublist操作也会影响list。
public class ListSubList { public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); List<Integer> sublist = new ArrayList<Integer>(); //生成的List数据 for(int i = 1; i <= 10; i++) { list.add(i); } sublist = list.subList(2, 4); System.out.println("sss"); // sublist.clear(); list.clear(); System.out.println("sss"); Iterator i = sublist.iterator(); while(i.hasNext()) { System.out.println(i.next()); } } }
在eclipse中设置一个断点,很容易可以看出来。
原来作者实现的理解 CyclicBarrier ExecutorService
public class CountListIntegerSum { private Long sum=0L;//存放整数的和 private CyclicBarrier barrier;//障栅集合点(同步器) private List<Integer> list;//整数集合List private int threadCounts;//使用的线程数 public CountListIntegerSum(List<Integer> list,int threadCounts) { this.list=list; this.threadCounts=threadCounts; } /** * 获取List中所有整数的和 * @return */ public long getIntegerSum(){ ExecutorService exec=Executors.newFixedThreadPool(threadCounts); int len=list.size()/threadCounts;//平均分割List //List中的数量没有线程数多(很少存在) if(len==0){ threadCounts=list.size();//采用一个线程处理List中的一个元素 len=list.size()/threadCounts;//重新平均分割List } barrier=new CyclicBarrier(threadCounts+1); for(int i=0;i<threadCounts;i++){ //创建线程任务 if(i==threadCounts-1){//最后一个线程承担剩下的所有元素的计算 exec.execute(new SubIntegerSumTask(list.subList(i*len,list.size()))); }else{ exec.execute(new SubIntegerSumTask(list.subList(i*len, len*(i+1)>list.size()?list.size():len*(i+1)))); } } try { barrier.await();//关键,使该线程在障栅处等待,直到所有的线程都到达障栅处 } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName()+":Interrupted"); } catch (BrokenBarrierException e) { System.out.println(Thread.currentThread().getName()+":BrokenBarrier"); } exec.shutdown(); return sum; } /** * 分割计算List整数和的线程任务 * @author lishuai * */ public class SubIntegerSumTask implements Runnable { private List<Integer> subList; public SubIntegerSumTask(List<Integer> subList) { this.subList=subList; } public void run() { long subSum=0L; for (Integer i : subList) { subSum += i; } synchronized(sum){//在CountListIntegerSum对象上同步 sum+=subSum; } System.out.println("分配给线程:"+Thread.currentThread().getName()+"那一部分List的整数和为:\tSubSum:"+subSum); try { barrier.await();//关键,使该线程在障栅处等待,直到所有的线程都到达障栅处 } catch (InterruptedException e) { System.out.println(Thread.currentThread().getName()+":Interrupted"); } catch (BrokenBarrierException e) { System.out.println(Thread.currentThread().getName()+":BrokenBarrier"); } } } public static void main(String[] args) { List<Integer> list = new ArrayList<Integer>(); int threadCounts = 10;//采用的线程数 //生成的List数据 for (int i = 1; i <= 1000000; i++) { list.add(i); } CountListIntegerSum countListIntegerSum=new CountListIntegerSum(list,threadCounts); long sum=countListIntegerSum.getIntegerSum(); System.out.println("List中所有整数的和为:"+sum); } }
程序中采用了10个线程来分别计算一个大的list中的所有数的和,利用了CyclicBarrier,这个程序正好展示了如何利用CyclicBarrier,这里在新建CyclicBarrier 时传替了一个11参数进去,就是当有11个线程到达这个樟栅时,才放开所有的线程,让其运行barrier.await();之后的语句。这里正好也比较一下CyclicBarrier 与CountDownLatch(http://xmind.iteye.com/blog/717140)的区别,CyclicBarrier主要可以用于许多线程等待到同一时间点同时发行,CountDownLatch可用于一个线程等待多个线程。显然,这里更适合用CountDownLatch。同时这里还用到了ExecutorService,ExecutorService对于启动新建和启动线程提供了方便。
原来作者实现的理解 ExecutorService.invokeAll() Callable Future
public class CountSumWithCallable { public static void main(String[] args) throws InterruptedException, ExecutionException { int threadCounts =9;//使用的线程数 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); } }
最简单直接的一种实现方法,exec.invokeAll负责运行所有的callList,把结果返回到List<Future<Long>> ,程序一直阻塞到所有运行结束。很是适合这种把任务分割出去,最后又要汇总的情况。ExecutorService 不光只是提供了新建启动线程的方法,还提供了返回线程运行结果的方便啊。
发表评论
-
多线程的Wait返回它等待的下方
2014-08-15 14:16 518多线程的Wait返回它等待的下方。 Java Code ... -
多线程构造函数
2014-04-04 11:50 2044http://hi.baidu.com/tengxiaofe ... -
关于volatile
2013-01-28 13:24 574Volatile修饰的成员变量在每次被线程访问时,都强迫从共享 ... -
Java 多线程例子10 线程之间通信 wait notify notifyAll
2010-07-26 11:24 1274回答问题:http://www.iteye.com/probl ... -
java Thread 停止 开始 暂停
2010-07-23 15:07 241271,写了一个小程序: public class TestTh ... -
【转载】java Timer TimerTask
2010-07-22 11:31 17851,Timer Timer的实质上就是一个多线程,从它的类中 ... -
【转载】DelayQueue 的使用
2010-07-20 20:15 1295原文:http://ideasforjava.iteye.co ... -
多线程 CyclicBarrier
2010-07-20 19:38 921原文:http://blog.csdn.net/qian_34 ... -
java多线程 Semaphore CountDownLatch ScheduledExecutorService
2010-07-20 17:06 1800参考:http://www.ibm.com/developer ... -
java多线程 BlockingQueue 和 SynchronousQueues
2010-07-20 15:30 1424参考:http://www.ibm.com/developer ... -
JDK 7 中的 Fork/Join 模式
2010-07-20 10:59 1813参考1:http://www.ibm.com/develope ... -
Java 多线程例子10 控制线程的生命 stop
2010-07-19 21:13 1275在Thread类中stop已经不推荐大家使用了,因为使用sto ... -
Java 多线程例子9 线程之间通信 wait notify notifyAll
2010-07-19 20:07 2816下面参照《Java就业培训教材》写了一个相似的线程之间通信的例 ... -
Java 多线程例子8 线程状态
2010-07-19 17:27 1194原文:http://shihaiyang.iteye.com/ ... -
Java 多线程例子7 线程安全 死锁
2010-07-19 17:07 1474死锁:在多个线程里对多个同步对象具有循环依赖时常会出现死锁。最 ... -
Java 多线程例子6 线程安全 线程同步 同步代码块 同步函数
2010-07-18 18:06 2217线程安全 出现线程安 ... -
Java 多线程例子5 实际例子的讨论
2010-07-18 15:18 9911,网络聊天程序,如QQ。 发送信息和接受信息肯定要连个线程 ... -
Java 多线程例子4 继承Thread 实现Runnable
2010-07-16 19:48 16751,Runnable例子 class ThreadDemo ... -
Java 多线程例子3 联合线程 join()
2010-07-16 17:57 22361,联合线程实际上就是 ... -
Java 多线程例子2 前台线程(用户线程) 后台线程(守护线程 ) setDaemon
2010-07-16 15:16 28461,setDaemon(true)后就是后台线程(守护线程 ) ...
相关推荐
《java并发编程》中CountDownLatch和CyclicBarrier用法实例大全,几乎包含了所有重要的用法
java并发编程中CountDownLatch和CyclicBarrier的使用借鉴.pdf
java并发编程中CountDownLatch和CyclicBarrier的使用.pdf
CountDownLatch 和 CyclicBarrier 为线程同步的辅助工具,通过它可以做到使一条线程一直阻塞等待,直到其他线程完成其所处理的任务。
目录: 简介 1.1 并发编程与线程协作 1.2 CyclicBarrier概述 CyclicBarrier的基本用法 2.1 创建CyclicBarrier对象 2.2 await()方法 控制线程协作数量 ...CyclicBarrier与CountDownLatch的对比 最佳实践与注意事项
主要介绍了详解java CountDownLatch和CyclicBarrier在内部实现和场景上的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
Java并发编程一CountDownLatch、CyclicBarrier、Semaphore初使用 CountDownLatch、CyclicBarrier、Semaphore这些线程协作工具类是基于AQS的,看完这篇博客后可以去看下面这篇博客,了解它们是如何实现的。 Java并发...
java 高并发应用场景
CyclicBarrier是Java中的一个同步工具类,用于协调多个线程之间的同步。它的作用类似于CountDownLatch,可以让一个或多个线程等待其他线程执行完毕后再继续执行。 CyclicBarrier可以被看作是一个屏障,当所有线程都...
CyclicBarrier和CountDownLatch一样,都是关于线程的计数器。用法略有不同,测试代码如下:
目录: 简介 1.1 并发编程与线程同步 1.2 CountDownLatch概述 CountDownLatch的基本用法 2.1 创建CountDownLatch对象 2.2 await()方法 ...CountDownLatch与CyclicBarrier的对比 最佳实践与注意事项
主要介绍了Java并发编程:CountDownLatch与CyclicBarrier和Semaphore的实例详解的相关资料,需要的朋友可以参考下
CyclicBarrier的使用以及注意事项
1. 什么是线程? 2. 线程和进程有什么区别? 3. 如何在 Java 中实现...7. Java 中 CyclicBarrier 和 CountDownLatch 有什么不同? 8. Java 内存模型是什么? 9. Java 中的 volatile 变量是什么? ......... ........
用CyclicBarrier,reentrantlock,condition来完成同时购买,同步购买的功能 JUC系列之模拟抢票(N人同时抢票,票不足系统补仓,N-M人继续抢票) http://blog.csdn.net/crazyzxljing0621/article/details/77891620
NULL 博文链接:https://hubowei1.iteye.com/blog/2312471
在涉及一组固定大小的线程的程序中,这些线程必须不时地互相等待,此时CyclicBarrier很有用。因为该barrier在释放等待线程后可以重用,所以称它为 循环 的barrier。 CyclicBarrier 支持一个可选的 Runnable命令,...