论坛首页 Java企业应用论坛

淘宝面试题:如何充分利用多核CPU,计算很大的List中所有整数的和

浏览 94798 次
该帖已经被评为良好帖
作者 正文
   发表时间:2010-07-13  
fork/join处理这个貌似是最合适的
0 请登录后投票
   发表时间:2010-07-13   最后修改:2010-07-13
fork/join处理这个貌似是最合适的-----晕,一不小心发重复了,修改一下,顺便发个相关链接:
http://www.ibm.com/developerworks/cn/java/j-lo-forkjoin/

0 请登录后投票
   发表时间:2010-07-13  
也许是用synchronized写异步任务习惯了,感觉新的同步模型还不如旧的P、V模型来的清晰易读啊,嗨~~~out了~~
0 请登录后投票
   发表时间:2010-07-13  
linliangyi2007 写道
也许是用synchronized写异步任务习惯了,感觉新的同步模型还不如旧的P、V模型来的清晰易读啊,嗨~~~out了~~

哥们我也是看lz的代码很不爽啊,自己控制线程同步加锁比较爽点,util.concurrent代码看起来难读的很
0 请登录后投票
   发表时间:2010-07-13  
kakaluyi 写道
linliangyi2007 写道
也许是用synchronized写异步任务习惯了,感觉新的同步模型还不如旧的P、V模型来的清晰易读啊,嗨~~~out了~~

哥们我也是看lz的代码很不爽啊,自己控制线程同步加锁比较爽点,util.concurrent代码看起来难读的很


嘿嘿。这个也不能太全面,util.concurrent毕竟能帮助我们写出更加简单而健壮的程序,当然如果水平很高的话可以自己控制,自由度大,但是如果用的多的话会可能比较乱。
0 请登录后投票
   发表时间:2010-07-13  
这里发个回帖感谢所有人的参与,感谢大家的集思广益,感谢大家的激烈的讨论,是你们让这个帖子更有价值。

楼主我在原帖(楼主贴)底部啰嗦了一些话,想看的话可以看看。
0 请登录后投票
   发表时间:2010-07-13  
看过主贴和评论,学习了。
发现的问题:
(1)CyclicBarrier不适合这种并发任务。单个线程完成任务之后完全可以终止了,没必要全部等待着,这可能是很大的资源浪费。使用CountDownLatch也会有这个问题。
(2)楼主使用了线程同步,考虑到同步的代价,这是可能是个很大的时间浪费。
(3)楼主使用CyclicBarrier的唯一用处在于,保证所有的任务都完成了。但是杀鸡焉用牛刀?这可能是...的浪费

  其实实现这样的功能,可以不用那么复杂,而且可以不用加锁。这里需要一个AtomicInteger(设为atom)。每个线程获得自己的sublist求和任务之后,计算一个和,保存到某个成员变量(设为subsum)中(如某楼上所说),把那个atom加1,然后结束。
  在主方法中,启动所有线程,然后添加一条语句,等待所有线程完成任务:
while(atom.intValue()<threadCounts)
  Thread.yield();
最后从所有死掉的线程对象中,获取subsum并累加即可。

0 请登录后投票
   发表时间:2010-07-13   最后修改:2010-07-14
夜枫舞影 写道

那假设我换个例子呢,count所有大于10的,c#也有一句话方法吗。


你放心,C#并发编程的能力强得很的,也是一句话

collection.AsParallel<int>().Where<int>(i => i > 10).Sum()


java在并发方面落后得很呢...

如果考虑越界的话,就采用BigInteger
BigInteger result=BigInteger.Zero;
Parallel.For(0, collection.Count, i =>{result = result + i;});


更简单的
BigInteger result=BigInteger.Zero;
Parallel.ForEach(i =>{result = result + i;});


.NET默认会为你打开和CPU core一样多的线程数。
0 请登录后投票
   发表时间:2010-07-14  
飞雪无情 写道
captmjc 写道
来不及看所有的恢复,但是提醒大家注意,在注意算法的同时,注意越界的问题。

两个int相加,都可能越界,何况“很大的List”。所以实战的话,可能需要BigInteger。

而BigInteger的话,更体现了线程的优势。N个较小的BI相加,比一个巨大的BI参与的计算快多了。

同意你说的越界问题,不过采用BigInteger我倒没试过,因为它的加减乘除等操作是程序实现的,不一定比(+-*/)操作符快吧。


BigInteger我做过阶乘,分组相乘,(1*9*17...) * (2*10*18...) 速度超快。
0 请登录后投票
   发表时间:2010-07-14  
captmjc 写道
飞雪无情 写道
captmjc 写道
来不及看所有的恢复,但是提醒大家注意,在注意算法的同时,注意越界的问题。

两个int相加,都可能越界,何况“很大的List”。所以实战的话,可能需要BigInteger。

而BigInteger的话,更体现了线程的优势。N个较小的BI相加,比一个巨大的BI参与的计算快多了。

同意你说的越界问题,不过采用BigInteger我倒没试过,因为它的加减乘除等操作是程序实现的,不一定比(+-*/)操作符快吧。


BigInteger我做过阶乘,分组相乘,(1*9*17...) * (2*10*18...) 速度超快。



多谢你提供例子,我要好好的理解下BigInteger。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics