当一个素数被发现时,我必须阻止它。当我在 while
,只会发生一个线程进程。但是,应该发生多线程操作,但是当找到prime时,所有操作都应该停止。
初始值 i
在控制部分已经改变。
我想做的是找到素数使用锁和同步。
public abstract class NumberGenerator {
private boolean isStop;
public abstract int generateNumber();
public void stop() {
this.isStop = true;
}
public boolean isStopped() {
return isStop;
}
}
public class IntegerNumberGenerator extends NumberGenerator {
private Random random;
int randomAtama;
public IntegerNumberGenerator() {
this.random = new Random();
}
@Override
public int generateNumber() {
return random.nextInt(100) + 1;
}
}
public class PrimeNumberChecker implements Runnable {
private NumberGenerator generator;
private Lock lock = new ReentrantLock();
public Condition continueLock = lock.newCondition();
public PrimeNumberChecker(NumberGenerator generator) {
this.generator = generator;
}
@Override
public void run() {
while (!generator.isStopped()) {
int number = generator.generateNumber();
System.out.println(Thread.currentThread().getName() + " generated " + number);
if (check(number)) {
System.out.println(number + " is prime !");
generator.stop();
}
}
}
public static boolean check(int number) {
boolean result = true;
for (int i = 2; i <= number / 2; i++) {
if ((number % i) == 0) {
result = false;
}
}
return result;
}
}
public class Driver {
public static void main(String[] args) {
ExecutorService executorService = Executors.newCachedThreadPool();
NumberGenerator numberGenerator = new IntegerNumberGenerator();
for (int i = 0; i < 5; i++) {
executorService.execute(new PrimeNumberChecker(numberGenerator));
}
executorService.shutdown();
}
}
2条答案
按热度按时间xcitsw881#
您可以将检查方法优化为:
一旦你知道这个数不是素数,你就可以早点返回。
当我找到一个素数时,我必须阻止它。如果在synchronized while之前使用它,则只会发生一个线程进程。应该发生多线程操作,但在找到素数时应该停止。
您可以通过将第一个volatile添加到
isStop
标志:然后检查
generator.isStopped()
(也)在确定一个数是否为素数的方法中:最后,您需要在读取
check
方法,因为可能会发生多个线程同时查找素数的情况。因此,调整代码以:volatile在这里是不够的,因为多个线程可能设法进入
在他们中的一个打电话之前
generator.stop()
;. 制造变量isStop
AtomicBoolean
因为同样的原因,光靠自己也无济于事。关键是陈述
!generator.isStopped()
以及generator.stop();
必须在相同的关键区域内执行,要么使用同步的,要么在同一个go中原子地执行两个操作。因此,对于AtomicBoolean
要工作,您必须执行以下操作:和
因为
getAndSet
如果以原子方式完成,就不会有多个线程打印出它们的素数的风险。我想做的是找到素数使用锁和同步。
如果您的意思是只使用一个或另一个(因为您不需要同时使用这两个),那么您可以执行以下操作:
即使没有挥发性物质,这也能起作用。
gmxoilav2#
线程本身应该知道抽象类中的“何时应该停止”逻辑,而不是该逻辑。因此,我将在runnable类中添加一个atomicboolean作为标志,并添加一个stop()方法来处理它。然后run方法将寻找每当这个布尔值改变时停止的atomicboolean。
像这样: