是不是可以“加入”中断的线程?

时间:2015-12-06 01:38:16

标签: java android multithreading

我有一个纸牌游戏应用程序,其中“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()));

2 个答案:

答案 0 :(得分:4)

加入线程既不必要......也不足以防止资源泄漏。

实际上:

  • 当线程终止 1 时,线程堆栈有资格进行回收。如果线程没有对中断做出适当的响应(即通过终止自身),那么你就会有资源泄漏。

  • 线程终止后,Thread对象有资格进行回收,并且对象没有可访问的引用。但是Thread对象的泄漏是一个简单的内存泄漏,而不是正常意义上的资源泄漏。

1 - 当run()方法终止时,线程终止,通常(通过返回)或异常终止(由于未经检查的异常的传播)。

答案 1 :(得分:0)

除了等待线程t.join()死亡之外,调用t不会执行任何操作。它根本不做线程t