下面 是一个求素数的问题 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("等待线程被中断");
}
}
}
我运行了一下时间 ,后面的要漫出很多谁机器比较给力 帮忙运行一下。
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到 10000000这些数?比如你开10个线程 分别处理 1-1000000 2000000-3000000 以此类推, 那么在不同区间上各个线程的处理时间是不行的, 所以我采用了我上面的方法。 每个线程处理一个数后 就去 Counter取 Counter是各个线程共享的,所以保证线程之间的获得任务公平性。 但是我感觉应该是 原子自加操作比较费时 。如果按你说的 时间会快些,是因为不需要显示的同步,所以节省了开销。我之前做了一个 1加到10000000 的 双线程确实比单线程快一些。
这个里面应该是 因为产生待处理数的过程耗时比较长 ,因为它无法利用缓存。 前面的处理应该数组元素都被缓冲到缓存中了 ,所以取得比较快。 而后面的例子要一直从内存中取。