简体   繁体   中英

Java - how to interrupt a busy thread

I am trying to interrupt a thread that is running AES encryption on a file. That can take a while, so far I have come up with this.

This body is inside button activate event. When the user clicks the button again (else clause). The thread should be interrupted, but I would be happier if I could stop the thread completely. But that is deprecated.

Anyway, the thread ignores the .interrupt() and continues to execute the aes256File. It does raise the fileEncryptThread.isInterrupted() flag, but from cpu usage I can see it still continues to crunch the file.

I have read the guide on safe stopping of threads, but I have no desire to completely redesign my already slow AES implementation to be checking for out of class interrupts flags...

    fileEncryptThread = new FileThread() // new thread please
    {
        @Override
        public void run()
        {
            String result = "";
            result = MyCrypto.aes256File(enInPath,
                                         enOutPath, 
                                         charsToString(passT.getPassword()),
                                         sec);
            if (!"".equals(result)) // error handling
            {
                JOptionPane.showMessageDialog(null,result);
            }
        }
    };
    fileEncryptThread.start();
  }
  else // if stop clicked
  {
      fileEncryptThread.interrupt();

In order to effectively interrupt a thread, that thread has to be written in an interruptible way. That is, check the

Thread.currentThread().isInterrupted()

boolean and act thereupon.

In your app, you should verify that

result = MyCrypto.aes256File(enInPath, enOutPath, charsToString(passT.getPassword()), sec);

acts in such a manner (if its a 3rd party library, it should be javadoc'ed). If it's not interruptible, you'd choose another implementation for encryption.

AFAIK, the only safe way for a thread to terminate is to return from the "main"-method of the thread (usually run() in Runnable or Thread). You could for example use a while(<some class member boolean>) -loop inside your MyCrypto.aes256File -method and set the boolean to false so the thread will fall out of the loop and exit returning a value indicating that the process was not completed.

One other approach that may be possible, (I don't know the AES algorithm well enough), would be split up the file reading from the encryption. A read thread would fill large-ish buffers from the file and queue them to the encryption thread. The encryption thread would process the buffers and queue the 'used' ones back to the reader thread. This allows both easy stopping of both threads while also probably improving performance, especially on multi-core machines, by moving I/O waits out of the encrypter. The encryption thread would probably never have to wait for a disk read - a temporary wait by the reader thread for a disk head move would not matter if the encryption thread had enough buffers to go at in the queue, (even on a single-core machine). The fixed number of buffers and the two (blocking, thread-safe), queues provide flow-control should the reader thread get ahead of the encrypter.

The actual stopping mechanism then becomes somewhat trivial. The gain in avoiding disk latency would overwhelm the time wasted checking a flag occasionally, eg. just before going to the queue for the next buffer.

Queueing buffers then also allows the possibility of adding sequence numbers to the buffers and so allowing all cores to work on the encryption.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM