使用wait、notify简单实现并行计算
2016-03-26 22:41
387 查看
jdk1.5之后可以使用 Executor、Callable和Future实现多个线程协同工作。
比如有这样的场景:需要从3个数据库中分别查询数据,最后合并结果返回。
如果不用多线程的话,只能先查第1个库,查完放在List中,接着再查第2个库,接着再查第3个库,类似的代码可能是这样的:
这里selectDB1()、selectDB谐()和selectDB3() 完全可以并行执行,他们之间没有依赖关系,如果我们用3个线程并行地去调用这3个方法,3个方法都有结果返回后再合并,则在多核的环境下应该可以得到更好的查询速度。
而在jdk1.5之前没有 Executor、Callable和Future,那我们如果使用多线程来实现并行计算呢?
下面的代码演示了使用3个线程来并行计算从1累加到300000000L之和。
test3Thread()用3个线程来计算,test1Thread() 只用一个线程来计算,比较下来 test3Thread()比test1Thread()快1倍。
比如有这样的场景:需要从3个数据库中分别查询数据,最后合并结果返回。
如果不用多线程的话,只能先查第1个库,查完放在List中,接着再查第2个库,接着再查第3个库,类似的代码可能是这样的:
List<T> result1 = selectDB1(); List<T> result2 = selectDB2(); List<T> result3 = selectDB3(); // 合并结果返回 result1.addAll(result2); result1.addAll(result3);
这里selectDB1()、selectDB谐()和selectDB3() 完全可以并行执行,他们之间没有依赖关系,如果我们用3个线程并行地去调用这3个方法,3个方法都有结果返回后再合并,则在多核的环境下应该可以得到更好的查询速度。
而在jdk1.5之前没有 Executor、Callable和Future,那我们如果使用多线程来实现并行计算呢?
下面的代码演示了使用3个线程来并行计算从1累加到300000000L之和。
test3Thread()用3个线程来计算,test1Thread() 只用一个线程来计算,比较下来 test3Thread()比test1Thread()快1倍。
public class TestMoreThread { /** * 只用一个线程计算 */ public static void test1Thread(){ long result = 0L; for(long i=0;i<300000000L;i++){ result += i; } } /** * 使用3个线程计算 */ public static void test3Thread(){ Object lock = new Object(); //启动3个线程分成3断同时计算 Computer c1 = new Computer("T1", lock, 0, 100000000L); Computer c2 = new Computer("T2", lock, 100000001L, 200000000L); Computer c3 = new Computer("T3", lock, 200000001L, 300000000L); new Thread(c1).start(); new Thread(c2).start(); new Thread(c3).start(); // 判断3个线程是否都计算完成 while (!c1.getStatus() || !c2.getStatus() || !c3.getStatus()) { synchronized (lock) { try { // 在这里释放锁和CUP控制权,当有子线程的状态改变后会唤配它继续执行 lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } } // 在这里合并3个线程的计算结果 System.out.println((c1.getResult()+c2.getResult()+c3.getResult())); } public static void main(String[] args) { long begin = System.currentTimeMillis(); test3Thread(); System.out.println("Take me for "+(System.currentTimeMillis()-begin)+" ms"); } } /** * 执行子任务的子线程 * @author bruce * */ class Computer implements Runnable { private boolean status = false; private long result; private Object lock; private String name; private long begin; private long end; public Computer(String name, Object lock, long begin, long end) { this.begin = begin; this.end = end; this.lock = lock; this.name = name; } @Override public void run() { long sum = 0; for (long i = begin; i <= end; ++i) { sum += i; } this.result = sum; this.status = true; //计算完后唤醒主线程 synchronized (lock) { lock.notify(); } System.out.println(name+":"+sum); } public long getResult(){ return this.result; } public boolean getStatus(){ return this.status; } }
相关文章推荐
- 浙江科技学院第十三届程序设计竞赛 1008:A Heavy Rainy Day【贪心】
- hdoj--A Heavy Rainy Day(贪心好题)
- LeetCode172. Factorial Trailing Zeroes
- 增加samba用户提示Failed to add entry for user
- Educational Codeforces Round 5 E. Sum of Remainders
- AIDL调用指南
- 加入百度地图遇到 framework not found BaiduMapAPI***
- 在main方法中调用service
- HDU1021-Fibonacci Again,,找规律就好了~~~
- golang sync WaitGroup
- Hive连接Mysql---FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask.
- Eval()和DataBinder Eval(Container DataItem,)的区别及用法
- Airplane mode的三种切换方式
- PAT (Advanced Level) Practise 1106 Lowest Price in Supply Chain (25)
- 你应该知道的最好Webmail邮件客户端,
- 8款世界级Webmail工具推荐
- jps 报process information unavailable解决办法
- coderforce Educational Codeforces Round 10 C. Foe Pairs(贪心)
- FATAL: Peer authentication failed for user "geo_rails_test_creator"
- Codeforences Educational Round10 C. Foe Pairs