我正在制作一个java程序,我必须找到所有素数和素数的数量高达2亿。我必须使用具有静态全局变量的试验除法,所有线程共享以保存下一个要检查的数字(如果是素数)。当它找到一个素数时它将它添加到一个数组然后在完成时显示该数组。这是我到目前为止所有的线程和所有线程都显示相同数量的素数,因为素数的总数可以由任何人帮助。
主 -
//*import java.util.Scanner;
public class MultiThreadedPrimeFinder {
static final int nThreads = 2;
public static void main(String[] args) throws InterruptedException{
int t;
int total = 0;
PrimeThread[] pthreads = new PrimeThread[nThreads];
//*Scanner kb = new Scanner(System.in);
//*System.out.println("Enter a Positive Integer: ");
//*long num = kb.nextLong();
long starttime, endtime, runtime, a = 0;
starttime = System.currentTimeMillis();
for(int i = 0; i <10000000; i ++)
a+=i;
for (t=0; t<nThreads; t++)
{
pthreads[t] = new PrimeThread();
pthreads[t].start();
}
for (t=0; t<nThreads; t++)
{
pthreads[t].join();
System.out.println("Thread "+t
+" Prime count: "+ pthreads[t].count);
}
total = PrimeThread.count;
System.out.println("Total prime count: "+total);
for (int i=0;i<100; i++)
System.out.println(""+i+": "+PrimeThread.primes[i]);
endtime = System.currentTimeMillis();
runtime = endtime - starttime;
System.out.println("The run time is " +runtime +" milliseconds");
}
}
班级 -
public class PrimeThread extends Thread{
static long nextNumber=3;
static final long max = 1000;
public static int count=0;
public long thread = 100;
public static long[] primes = new long[100000];
public void run() {
long myNumber;
while ((myNumber=getNextNumber())<=max) {
primes[0] = 2;
if (prime(myNumber)) {
primes[count++] = myNumber;
}
}
}
public static synchronized long getNextNumber() {
long n = nextNumber;
nextNumber +=2;
return n;
}
public boolean prime(long n) {
int i;
for (i=3; i * i<=n; i+=2)
if (n%i==0) return false;
return true;
}
}
输出看起来像这样
Thread 0 Prime count: 167
Thread 1 Prime count: 167
Total prime count: 167
0: 2
1: 5
2: 7
3: 11
4: 13
5: 17
6: 19
7: 23
8: 29
9: 31
10: 37
11: 41
12: 43
13: 47
14: 53
15: 59
16: 61
17: 67
18: 71
19: 73
20: 79
21: 83
22: 89
23: 97
24: 101
25: 103
26: 107
27: 109
28: 113
29: 127
30: 131
31: 137
32: 139
33: 149
34: 151
35: 157
36: 163
37: 167
38: 173
39: 179
40: 181
41: 191
42: 193
43: 197
44: 199
45: 211
46: 223
47: 227
48: 229
49: 233
50: 239
51: 241
52: 251
53: 257
54: 263
55: 269
56: 271
57: 277
58: 281
59: 283
60: 293
61: 307
62: 311
63: 313
64: 317
65: 331
66: 337
67: 347
68: 349
69: 353
70: 359
71: 367
72: 373
73: 379
74: 383
75: 389
76: 397
77: 401
78: 409
79: 419
80: 421
81: 431
82: 433
83: 439
84: 443
85: 449
86: 457
87: 461
88: 463
89: 467
90: 479
91: 487
92: 491
93: 499
94: 503
95: 509
96: 521
97: 523
98: 541
99: 547
The run time is 17 milliseconds
答案 0 :(得分:2)
你有
public static int count=0;
跟踪总计得到的素数。由于它是static
,pthreads[0].count == pthreads[1].count == PrimeThread.count
。要查看各个线程检索的素数,请添加一个实例计数器:
public int myCount = 0;
....
primes[count++] = myNumber;
myCount++;
...
System.out.println("Thread "+t
+" Prime count: "+ pthreads[t].myCount);
另外,为了防止count ++的交错,你应该在递增时同步。
答案 1 :(得分:0)
无法帮助您解决多线程问题,我发现此页面试图解决类似问题,但您的主要搜索算法有几个问题:
首先,在您的run()
方法中,为什么在while循环中有primes[0] = 2
?每当它只需要设置一次时它就会被设置。
其次,你正在跳过3,这是一个素数。发生这种情况的原因是您将myNumber
设置为3,但在检查之前请调用getNextNumber()
。将myNumber
初始化为1。
答案 2 :(得分:-1)
尽管@Saposhiente的回答是正确的,但我想发布OP的正确版本以考虑并找出其他小问题
线程类:
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
public class PrimeThread extends Thread {
final public static long[] primes = new long[100000];
static {
primes[0] = 2; // init 1st prime only 1 time
};
final static AtomicLong nextNumber = new AtomicLong(3L);
final static long MAX = 1000L;
public int count = 0; // non static local count
public static AtomicInteger totalCount = new AtomicInteger(); // static global count
public void run() {
long myNumber;
while ((myNumber = nextNumber.getAndAdd(2L)) <= MAX)
if (prime(myNumber)) {
primes[totalCount.incrementAndGet()] = myNumber; // note increment and get instead of get and increment
count++;
}
}
public static boolean prime(final long n) {
final long maxI = (long) Math.sqrt(n); // faster than calculation of i*i each time
for (long i = 3; i <= maxI; i += 2)
if (n%i==0) return false;
return true;
}
}
主程序:
public class MultiThreadedPrimeFinder {
static final int nThreads = 2;
public static void main(final String[] args) {
final PrimeThread[] pthreads = new PrimeThread[nThreads];
final long starttime = System.nanoTime();
for (int i = 0; i < nThreads; i++) {
pthreads[i] = new PrimeThread();
pthreads[i].start();
}
try {
for (int i = 0; i < nThreads; i++)
pthreads[i].join();
} catch (InterruptedException e) {
}
final long endtime = System.nanoTime(); // measure only actual execution, without any system calls
System.out.println("The run time is " + ((endtime - starttime) / 1000000L) + " milliseconds");
for (int i = 0; i < nThreads; i++)
System.out.println("Thread " + i + " Prime count: " + pthreads[i].count); // output each thread's count
System.out.println("Total prime count: " + PrimeThread.totalCount.get()); // output total count
for (int i = 0; i < 100; i++)
System.out.println(""+i+": "+PrimeThread.primes[i]);
}
}