让我们说我有一个针对给定参数做某事的算法。如果算法运行时间超过100毫秒,那么我想停止它并再次尝试使用不同的参数。
我在下面发布了测试随机参数算法的代码......以及我认为代码可能如下所示:
public class StopThread {
private Lock lock = new ReentrantLock();
public static void main(String... args) {
System.out.println("Starting threads...");
(new StopThread()).startThreads(100);
}
private void startThreads(int nrOfThreads) {
for (int i = 0; i < nrOfThreads; i++) {
startThread(i, (long) (Math.random() * 10000000000l));
System.out.println("Started thread number " + (i + 1));
}
}
private void startThread(final int number, final long load) {
Thread workerThread = new Thread() {
@Override
public void run() {
try {
lock.lock();
doAlgorithmWork(load);
} finally {
System.out.println("Thread " + (number + 1) + " finished...");
lock.unlock();
}
}
};
Thread timerThread = new Thread() {
@Override
public void run() {
try {
sleep(100);
} catch (InterruptedException e) {
}
}
};
workerThread.start();
timerThread.start();
do {
if (!workerThread.isAlive() || !timerThread.isAlive()) {
workerThread.stop();
timerThread.stop();
}
} while (!workerThread.isAlive() && !timerThread.isAlive());
}
protected void doAlgorithmWork(long load) {
while (load-- > 0) {
}
}
}
我觉得这个问题应该已经有了答案,但是我发现到现在为止看起来很复杂,而且我不知道如何使用它。我对线程知之甚少,如果你能发布一些代码,我将不胜感激。
答案 0 :(得分:0)
一个非常简单的解决方案如下:
private void startThreads(int nrOfThreads) {
for (int i = 0; i < nrOfThreads; i++) {
Thread worker = new Thread() {
@Override
public void run() {
doAlgorithmWork((long) (Math.random() * 10000000000l));
}
}
worker.start();
worker.join(100); //block until either the thread is done, or 100ms passed
if (worker.isAlive()) worker.stop(); //if thread is still alive, stop it
}
}
这将实现您的目标,但是会遇到许多缺点&#34;
doAlgorithm
的所有调用都是一个接一个地执行,而不是并行执行,因此您只使用机器的单个核心); Thread.stop()
方法。一种优选的方法是改为停止&#34;停止&#34;标记设置为true(代替stop()
调用),并且还会在doAlgorith
中不断检查; 更新:
为了避免弃用的stop()
调用,您需要在工作线程中添加一个标志,创建一个单独的类,如下所示:
public class Worker implements Runnable {
private volatile boolean stopped = false;
public void stop() {
stopped = true;
}
@Override
public void run() {
doAlgorithmWork((long) (Math.random() * 10000000000l));
}
private void doAlgorithmWork(long load) {
while (!stopped && load-- > 0) {
//calculation
}
}
}
然后你的跑步者看起来像这样:
private void startThreads(int nrOfThreads) {
for (int i = 0; i < nrOfThreads; i++) {
Thread worker = new Thread(new Worker());
worker.start();
worker.join(100); //block until either the thread is done, or 100ms passed
if (worker.isAlive()) worker.stop(); //if thread is still alive, stop it
}
}
您还可以为Worker创建一个构造函数,它接受load
值(而不是在Worker本身内生成它)。
请注意,如果doAlgorithm()
内的计算过于耗时,则线程可能会运行超过100毫秒(因为它总是完成循环中的每个计算)。如果这是一个问题,那么您的替代方法是中断线程(调用worker.interrupt()
将导致InterruptedException
方法中抛出run()
。