我的问题是:
public class Ex3_tester {
/** This class represents a basic implementation for Ex3testing file. */
public static double ENDLESS_LOOP=0.4;
public static void main(String[]args){
Ex3 ex3=new Ex3();
long n=33333331L;
boolean ans=ex3.isPrime(n,1);
System.out.println("n="+n+" isPrime "+ans);
}
/** DONOT change this function!,it must be used
* byEx3-isPrime(long,double) */
public static boolean isPrime(long n){
boolean ans=true;
if(n<2)throw new RuntimeException("ERR: the parameter to the isPrime function must be >1 (got "+n+")!");
int i=2;
double ns=Math.sqrt(n) ;
while(i<=ns&&ans){
if (n%i==0)
ans=false;
i=i+1;
}
if(Math.random()<Ex3_tester.ENDLESS_LOOP)//responsible to enter the program into endless loop
while(true);
return ans;
}}
好的,在Ex3_tester中我有一个函数isprime,它确定数字是否为素数。正如你所看到的那样,函数有时会变成无限循环。
我需要尝试为这个函数创建一个包装器 - 如果'isprime'在某个时候之后我不需要关闭它。我尝试了一切。我的最佳代码,直到现在有时得到答案,但如果函数变成无限循环它会抛出异常,但我看到程序继续运行(我可以在Eclipse控制台中看到)。 这是我的代码,直到现在:
package threads_task3;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
public class Ex3 implements Callable<Boolean>{
static long number;
AtomicBoolean interrupt=new AtomicBoolean(false);
public Boolean isPrime(long n, double d) {
number=n;
long time=(long)(d*1000);
ExecutorService primeFunction=Executors.newSingleThreadExecutor();
Future <Boolean> result=primeFunction.submit(this);
try {
Boolean finalresult= (result.get(time, TimeUnit.MILLISECONDS));
if(finalresult!=null){
primeFunction.shutdown();
return finalresult;
}
} catch (InterruptedException | ExecutionException | TimeoutException e) {
interrupt.set(true);
primeFunction.shutdown();
e.printStackTrace();
}
throw new RuntimeException();
}
@Override
public Boolean call() throws Exception {
while (!interrupt.get())
return Ex3_tester.isPrime(number);
throw new RuntimeException();
}
}
谢谢!
答案 0 :(得分:1)
要停止此功能,您别无选择,只能为其执行设置时间限制。如果执行时间超过k
秒,它应该已找到结果并已返回。 Java有一个有点笨拙的多线程模型,所以这样做需要几行代码,但是它有支持:
static class PrimeWrapper implements Runnable {
long n;
boolean result;
PrimeWrapper(long n){
this.n = n;
}
@Override public void run() {
result = isPrime(n);
}
}
public static void main(String[] args) {
long n = 7;
PrimeWrapper isPrime = new PrimeWrapper(n);
ExecutorService executor = Executors.newSingleThreadExecutor();
Future future = executor.submit(isPrime);
try {
future.get(3, TimeUnit.SECONDS);
} catch (Exception e) { // If future could not get() the result
future.cancel(true);
executor.shutdownNow();
System.out.println("isPrime went in to an infintie loop. Exiting...");
System.exit(-1);
}
future.cancel(true);
executor.shutdownNow();
System.out.println("Is " + n + " a prime number: " + isPrime.result);
}
最后我应该提一下,你可能永远不会自己编写像isPrime(long n)
这样的代码(即使在等效时间复杂度可能无法避免的实际领域)。
答案 1 :(得分:0)
好的,谢谢你的帮助
我试过这个并且它起作用了:
package threads_task3;
public class Ex3 implements Runnable{
static long number;
static Boolean result=null;
public Boolean isPrime(long n, double d) {
number=n;
long time=(long)(d*1000);
Thread prime=new Thread(this);
prime.setDaemon(true);
long start=System.currentTimeMillis();
prime.start();
long end=System.currentTimeMillis();
while( (end-start)<=time){
if (result!=null)
return result;
end=System.currentTimeMillis();
}
throw new RuntimeException();
}
@Override
public void run() {
result=Ex3_tester.isPrime(number);
}
}
但是,它不是最好的解决方案,因为如果我尝试将函数包装在很大的时间值中,那就说10秒它会从计算机中获取大量资源,如果有人有更好的想法或其他方式我会很高兴得到它!
谢谢!