我有一个纸牌游戏应用程序,其中“Droid”手必须在多个丢弃物中进行选择以优化其手牌。因此,我正在处理可能的丢弃选择,然后计算手部估值。我使用两种不同的方法进行估值;一个是详尽的,但可能非常昂贵,另一个是启发式的,非常快。一旦计算时间超过500毫秒,我就会从详尽的方法切换到启发式方法。我这样做是通过在可能的丢弃上启动线程,然后启动一个休眠线程。当它完成睡眠时,它会中断其他线程,然后我用启发式方法重新运行它们。
所有这一切都运行正常。但是在检查连接循环中的中断线程时,我立即抛出InterruptedException
,以便调用者知道重新运行计算。这样做,我就不会加入其他中断的线程。这是资源泄漏,还是最终会清理其他线程?
代码段如下: 开始我的主题:
for (Card disCard : cardsWithAdded) {
CardList cards = new CardList(cardsWithAdded);
cards.remove(disCard);
testHand[iThread] = new ThreadedHand(this.hand.getRoundOf(), cards, disCard, this.method, isFinalTurn); //creates new hand with replaced cards
t[iThread] = new Thread(threadGroup,testHand[iThread]);
t[iThread].start(); //calls meldAndEvaluate
iThread++;
}
在睡眠线程中中断它们:
public void run() {
final long sleepStartTime = System.currentTimeMillis();
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
// if interrupted, this means the other threads finished their work before the sleep ended
return;
}
threadGroup.interrupt(); //interrupt the other calculation threads
}
检查计算线程中的中断(循环中):
if (Thread.interrupted()) {
throw new InterruptedException();
}
在运行中设置标志:
public void run() {
threadStart = System.currentTimeMillis();
wasThreadInterrupted = false;
try {
this.meldAndEvaluate(this.method, EasyComputerPlayer.this , this.isFinalTurn);
} catch (InterruptedException e) {
//just break out of this thread
threadStop = System.currentTimeMillis();
wasThreadInterrupted = true;
}
threadStop = System.currentTimeMillis();
}
我在第一个被打断的线程中断的连接:
for (int iThread=0; iThread < this.numThreads; iThread++) {
try {
t[iThread].join();
} catch (InterruptedException e) {
throw new InterruptedException(String.format("%s-%s: findBestHandFinish interrupted in join()...",FiveKings.APP_TAG,Thread.currentThread().getName()));
}
//can only test this flag after we've rejoined the thread to this one
if (testHand[iThread].wasThreadInterrupted()) throw new InterruptedException(String.format("After join: Thread %s shows was-interrupted - throwing exception", t[iThread].getName()));
答案 0 :(得分:4)
加入线程既不必要......也不足以防止资源泄漏。
实际上:
当线程终止 1 时,线程堆栈有资格进行回收。如果线程没有对中断做出适当的响应(即通过终止自身),那么你就会有资源泄漏。
线程终止后,Thread
对象有资格进行回收,并且对象没有可访问的引用。但是Thread
对象的泄漏是一个简单的内存泄漏,而不是正常意义上的资源泄漏。
1 - 当run()方法终止时,线程终止,通常(通过返回)或异常终止(由于未经检查的异常的传播)。
答案 1 :(得分:0)
除了等待线程t.join()
死亡之外,调用t
不会执行任何操作。它根本不做到线程t
。