web-dev-qa-db-ja.com

Java)で実行中のスレッドを停止する方法

JavaをDOCXに変換するPDFベースのファイル変換ツールを使用していますが、入力ファイルのサイズが1 MBを超えている場合、変換中にスタックすることがあります。 100%CPUとより多くのメモリを利用し始め、実行を続けます。この継続的なスレッドを停止したいと思います。

  1. stop()関数が非推奨になっていることは知っています。
  2. スレッドが実行され続けるため、thread.interrupt();を呼び出しても役に立ちません。
  3. コードにループがないため、ループ内の割り込みフラグを確認できません

実行中のスレッドを停止する方法t。

public class ThreadDemo implements Runnable {

    Thread t;

    PdfToDocConversion objPdfToDocConversion;

    ThreadDemo() throws InterruptedException {

        t = new Thread(this);
        System.out.println("Executing " + t.getName());
        // this will call run() fucntion
        t.start();

        Thread.sleep(2000);

        // interrupt the threads
        if (!t.interrupted()) {
            System.out.println("Interrupted");

            t.interrupt();

        }

        System.out.println(t.isInterrupted()); // true 

        System.out.println(t.getName());

        System.out.println(t.isAlive());   /// still true 

        // block until other threads finish
        try {
            t.join();
        } catch (InterruptedException e) {
        }
    }

    public void run() {

        objPdfToDocConversion = new PdfToDocConversion();
        try {


    objPdfToDocConversion.convertDocToPdf();//inside this function thread got stuck

        } catch (InterruptedException e) {

            Thread.currentThread().interrupt(); 
            System.out.print(t.getName() + " interrupted:");
            e.printStackTrace();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public static void main(String args[]) {
        try {
            new ThreadDemo();
        } catch (InterruptedException e) {
                e.printStackTrace();
        }
    }
}
6
shirish sahu

Thread.interrupt()は、Threadオブジェクト内にスレッドを中断する必要があるというフラグのみを設定します。ターゲットスレッドがInterruptedExceptionをスローすることはありません。代わりに、割り込み可能なコードは、誰かが割り込みを要求したかどうかを確認するために、そのフラグを継続的にチェックする必要があります。そのコードは、通常はInterruptedExceptionをスローすることによってそれを処理する必要があります。

3
Smith_61

booleanフラグを使用して、スレッドを強制終了する独自のロジックを構築できます。

public class RunningThread implements Thread {

   private volatile boolean running = true;

   public void run() {

     while (running) {
        try {
            // Add your code here
        } catch (InterruptedException e) {
             if(!running){
                break;
             }
        }
     }
   }

   public void stopThread() {
       running = false;
       interrupt();
   }

}

ユースケースは次のとおりです。

RunningThread thread = new RunningThread();
thread.start(); // start the thread
thread.stopThread(); // stops the thread

上記のアプローチは、もともとGoogle開発者がフレームワーク(別名Volleyライブラリ)で使用しています。

3
Enzokie

いくつかの答えはvolatile boolean isRunningでループを停止することについて述べていますが、あなたの例ではループが見当たりません。スレッドを中断しても、実際には「今」は中断されません。 「そのような機会があればすぐにスレッドが中断される」とだけ書かれています。あなたの場合、PDFファイルを閉じてブール値でフラグを立てることをお勧めします-次にIOExceptionをキャッチでき、フラグが設定されている場合-それはあなたがこの状況を引き起こしたことを意味し、あなたはスレッドを終了します。

1
Wojciech Kazior

ブールフィールドを作成して、実行内で確認できます。

public class Task implements Runnable {

   private volatile boolean isRunning = true;

   public void run() {

     while (isRunning) {
         //do work
     }
   }

   public void kill() {
       isRunning = false;
   }

}
0
F4Code.com