关于多核的问题

meran 2011-08-16 09:16:21
下面 是一个求素数的问题 1 到10000000之间 统计出所有的素数

下面两种方法


package Algorithm.DP;

public class Prime {
int count=4;

public boolean isPrime(int i){
if(i%2==0)
return false;
if(i%3==0)
return false;
if(i%5==0)
return false;
if(i%7==0)
return false;

for(int j=8;j*j<=i;j++){
if(i%j==0)

return false;

}
count++;
return true;



}
public static void main(String [] args){
Prime prime=new Prime();
int [] array=new int[10000001];
for(int i=0;i<array.length;i++)
array[i]=i;

long startTime=System.currentTimeMillis();
for(int i=2;i<array.length;i++)
prime.isPrime(array[i]);

System.out.println("共有素数个数"+prime.count+" 计算花费时间"+(System.currentTimeMillis()-startTime));



}


}




package Algorithm.DP;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.*;

public class Concurrency implements Runnable{

static AtomicInteger count;
private final CountDownLatch latch;
private Counter counter;
public Concurrency(Counter counter,CountDownLatch latch){
this.latch=latch;
count=new AtomicInteger(4);
this.counter=counter;

}
public boolean isPrime(long temp){
if(temp%2==0)
return false;
if(temp%3==0)
return false;
if(temp%5==0)
return false;
if(temp%7==0)
return false;

for(int j=8;j*j<=temp;j++){
if(temp%j==0)

return false;

}
return true;
}




@Override
public void run() {

while(!Thread.interrupted()){

long temp=counter.nextNum();

if(temp==0)
Thread.currentThread().interrupt();
else
{
if(isPrime(temp))
{
count.incrementAndGet();
}

}

}
latch.countDown();


}



public static void main(String [] args) throws InterruptedException{
int numOfThreads=3;
long startTime=System.currentTimeMillis() ;
CountDownLatch latch=new CountDownLatch(numOfThreads);
Counter counter=new Counter();
ExecutorService exec=Executors.newCachedThreadPool();

for(int i=0;i<numOfThreads;i++)
exec.execute(new Concurrency(counter,latch));

exec.execute(new WaitingTask(latch,startTime));


}



}
class Counter{
final int TOTAL=10000000;
AtomicInteger num=new AtomicInteger(2);

public int nextNum(){
if(num.get()<=TOTAL)

return num.incrementAndGet();

return 0;

}

}
class WaitingTask implements Runnable{
private final CountDownLatch latch;
private final long startTime;

public WaitingTask(CountDownLatch latch,long startTime){
this.latch=latch;
this.startTime=startTime;
}

@Override
public void run() {
try {

latch.await();
System.out.println("共有"+Concurrency.count+"个素数"+"用时"+(System.currentTimeMillis()-startTime));
} catch (InterruptedException e) {
System.out.println("等待线程被中断");
}


}
}


我运行了一下时间 ,后面的要漫出很多。。。谁机器比较给力 帮忙运行一下。
...全文
86 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
meran 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 zhouyuqwert 的回复:]
友情帮测
第一个 共有素数个数664579 计算花费时间6119
第二个 共有662433个素数用时13554
[/Quote]

用我的电脑测出的结果一直是相同的。 我感觉我代码也没什么问题啊。。。
meran 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 cjf068 的回复:]
哈哈 当然多线程好咯 与分布没有关系撒
[/Quote]
我这个也是多线程。。。你没看明白么
meran 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 softroad 的回复:]
引用 5 楼 zhao251021539 的回复:

引用 3 楼 softroad 的回复:
10000000按线程个数分组,比如10个线程,把他分为10组,然后每个线程去搞不就行了。


你这么分肯定不行 , 因为这些树中间素数分布是不均匀的 , 而且数的大小不同,测试用时也不同啊


跟分布没关系吧,你不都要遍历10000000次?我只不过是分开而已。
[/Quote]

你看我的代码 我是用两个线程处理这些元素 ,按你说的 ,用两个线程处理, 你如何拆分1到 10000000这些数?比如你开10个线程 分别处理 1-1000000 2000000-3000000 以此类推, 那么在不同区间上各个线程的处理时间是不行的, 所以我采用了我上面的方法。 每个线程处理一个数后 就去 Counter取 Counter是各个线程共享的,所以保证线程之间的获得任务公平性。 但是我感觉应该是 原子自加操作比较费时 。

如果按你说的 时间会快些,是因为不需要显示的同步,所以节省了开销。

我之前做了一个 1加到10000000 的 双线程确实比单线程快一些。
这个里面应该是 因为产生待处理数的过程耗时比较长 ,因为它无法利用缓存。 前面的处理应该数组元素都被缓冲到缓存中了 ,所以取得比较快。 而后面的例子要一直从内存中取。
cjf068 2011-08-16
  • 打赏
  • 举报
回复
哈哈 当然多线程好咯 与分布没有关系撒
softroad 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 zhao251021539 的回复:]

引用 3 楼 softroad 的回复:
10000000按线程个数分组,比如10个线程,把他分为10组,然后每个线程去搞不就行了。


你这么分肯定不行 , 因为这些树中间素数分布是不均匀的 , 而且数的大小不同,测试用时也不同啊
[/Quote]

跟分布没关系吧,你不都要遍历10000000次?我只不过是分开而已。
meran 2011-08-16
  • 打赏
  • 举报
回复
谁能给我讲讲为什么会慢这么多 ??原子操作开销这么大么?
meran 2011-08-16
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 softroad 的回复:]
10000000按线程个数分组,比如10个线程,把他分为10组,然后每个线程去搞不就行了。
[/Quote]

你这么分肯定不行 , 因为这些树中间素数分布是不均匀的 , 而且数的大小不同,测试用时也不同啊
茫茫大海 2011-08-16
  • 打赏
  • 举报
回复
测试结果:
第一个 共有素数个数664579 计算花费时间6734
第二个 共有664579个素数用时17672
softroad 2011-08-16
  • 打赏
  • 举报
回复
10000000按线程个数分组,比如10个线程,把他分为10组,然后每个线程去搞不就行了。
softroad 2011-08-16
  • 打赏
  • 举报
回复
LZ真可爱。
阳明 to life 2011-08-16
  • 打赏
  • 举报
回复
友情帮测
第一个 共有素数个数664579 计算花费时间6119
第二个 共有662433个素数用时13554

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧