как избежать проверки прерывания потока везде в JAVA - PullRequest
0 голосов
/ 21 октября 2019

У меня есть два алгоритма A, B для вычислительного решения сложной задачи NP, что может занять много времени. Затем в основном потоке MI создайте threadA и threadB для алгоритма A и алгоритма B соответственно. Когда какой-либо из потоков A или ThreadB завершает вычисления или оба достигают тайм-аута, M вызывает прерывание для этих незавершенных потоков. M повторите эту процедуру для более чем 5000 тестовых случаев.

Поскольку алгоритмы A и B не имеют прерываемых операций, прерывание не вызовет исключения прерывания, таким образом, эти незавершенные потоки будут продолжать работать в фоновом режиме, что в конечном итогеисчерпывает кучу памяти, потому что все больше и больше незавершенных потоков.

Тогда мне нужно вручную проверить поток isInterrupted в обоих алгоритмах. Но я не хочу проверять их повсюду на предмет эффективности и читабельности кода.

Например, оригинальный алгоритм -

public class AlgA {
  public void run() {
    do1();
    do2();
    ...
    do100();
  }
}

И я не хочу

public class AlgA {
  public void run() throws InterruptedException {
    do1();
    check();
    do2();
    check();
    ...
    check();
    do100();
  }
  private void check() throws InterruptedException {
    if (Thread.interrupted()) {
      throw new InterruptedException();
    }
  }
}

Ответы [ 2 ]

0 голосов
/ 21 октября 2019

Вы можете сделать это просто следующим образом:

public class Test {
    public static void main(String args[]) {
        Thread threadA=new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        while(true) {
                            if (Thread.interrupted()) {
                                break;
                            }
                            //Continue the execution
                        }
                    }
                }
        );

        threadA.start();

        Thread threadB=new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        while(true) {
                            if (Thread.interrupted()) {
                                break;
                            }
                            //Continue the execution
                        }
                    }
                }
        );

        threadB.start();

        // Assigning someConditionMeets=true just for illustration.
        // In actual code someConditionMeets will store the result of some logic/function
        boolean someConditionMeets=true;
        if(someConditionMeets) {
            threadA.interrupt();
            threadB.interrupt();
        }
    }
}
0 голосов
/ 21 октября 2019

Один из способов может заключаться в проверке прерываний и вызове метода в каком-нибудь утилитарном методе:

public class AlgA {
  protected static void checkAndCall(Runnable action) 
      throws InterrruptedException {
    if (Thread.interrupted()) {
      throw new InterruptedException();
    }
    action.run()
  }

  public void run() {
    checkAndCall(this::do1);
    checkAndCall(this::do2);
    ...
    checkAndCall(this::do100);
  }
}
...