Java - как прервать занятый поток - PullRequest
0 голосов
/ 10 ноября 2011

Я пытаюсь прервать поток, в котором выполняется шифрование AES для файла. Это может занять некоторое время, пока я придумал это.

Это тело находится внутри кнопки активации события. Когда пользователь снова нажимает кнопку (предложение else). Поток должен быть прерван, но я был бы счастлив, если бы мог полностью остановить поток. Но это устарело.

В любом случае, поток игнорирует .interrupt () и продолжает выполнять файл aes256. Он поднимает флаг fileEncryptThread.isInterrupted (), но из-за использования процессора я вижу, что он все еще продолжает хрустить файл.

Я прочитал руководство по безопасной остановке потоков, но у меня нет желания полностью переделывать мою и без того медленную реализацию AES, чтобы проверять флаги прерываний вне класса ...

    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();

Ответы [ 3 ]

4 голосов
/ 10 ноября 2011

Чтобы эффективно прервать поток, этот поток должен быть записан прерываемым образом. То есть отметьте

Thread.currentThread (). IsInterrupted ()

логическое значение и действуйте по нему.

В вашем приложении вы должны убедиться, что

result = MyCrypto.aes256File (enInPath, enOutPath, charsToString (passT.getPassword ()), сек);

действует таким образом (если это сторонняя библиотека, он должен быть javadoc'ed). Если это не прервано, вы бы выбрали другую реализацию для шифрования.

2 голосов
/ 10 ноября 2011

AFAIK, единственный безопасный способ завершения потока - это возврат из "основного" метода потока (обычно run () в Runnable или Thread). Например, вы можете использовать while(<some class member boolean>) -loop внутри вашего MyCrypto.aes256File -method и установить логическое значение в false, чтобы поток выпадал из цикла и выходил, возвращая значение, указывающее, что процесс не был завершен.

1 голос
/ 11 ноября 2011

Еще один возможный подход (я недостаточно хорошо знаю алгоритм AES) - разделить чтение файла из шифрования.Поток чтения заполнил бы буферы большого размера из файла и поставил их в очередь в поток шифрования.Поток шифрования обработает буферы и поставит в очередь «использованные» обратно в поток считывателя.Это позволяет как легко останавливать оба потока, так и, вероятно, улучшать производительность, особенно на многоядерных машинах, перемещая ожидания ввода-вывода из шифратора.Потоку шифрования, вероятно, никогда не придется ждать чтения диска - временное ожидание потоком считывателя перемещения головки диска не будет иметь значения, если в потоке шифрования будет достаточно буферов в очереди (даже на одноядерном процессоре).машина).Фиксированное число буферов и две (блокирующие, поточно-ориентированные) очереди обеспечивают управление потоком, если поток считывателя опережает шифратор.

Фактический механизм остановки становится несколько тривиальным.Выигрыш во избежании задержки диска сократит время, потраченное на проверку флага, например.непосредственно перед переходом в очередь для следующего буфера.

Буферы очереди также позволяют добавлять порядковые номера в буферы и, таким образом, разрешать всем ядрам работать с шифрованием.

...