下面 是一个求素数的问题 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("等待线程被中断");
}
     

}
}
我运行了一下时间 ,后面的要漫出很多谁机器比较给力 帮忙运行一下。

解决方案 »

  1.   


    你看我的代码  我是用两个线程处理这些元素  ,按你说的 ,用两个线程处理, 你如何拆分1到 10000000这些数?比如你开10个线程 分别处理 1-1000000  2000000-3000000  以此类推, 那么在不同区间上各个线程的处理时间是不行的, 所以我采用了我上面的方法。  每个线程处理一个数后 就去 Counter取  Counter是各个线程共享的,所以保证线程之间的获得任务公平性。 但是我感觉应该是 原子自加操作比较费时 。如果按你说的 时间会快些,是因为不需要显示的同步,所以节省了开销。我之前做了一个 1加到10000000 的  双线程确实比单线程快一些。  
    这个里面应该是 因为产生待处理数的过程耗时比较长 ,因为它无法利用缓存。 前面的处理应该数组元素都被缓冲到缓存中了 ,所以取得比较快。  而后面的例子要一直从内存中取。