2016-05-31 2 views
0

все, мой английский плохой, но я постараюсь лучше всего объяснить свой вопрос.Java Concurrency in Practice Lising7.9

код следующим образом:

public class timedRun { 
    private static final ScheduledExecutorService cancelExec = newScheduledThreadPool(1); 

    public static void timedRun(final Runnable r, 
           long timeout, TimeUnit unit) 
      throws InterruptedException { 
     class RethrowableTask implements Runnable { 
      private volatile Throwable t; 

      public void run() { 
       try { 
        r.run(); 
       } catch (Throwable t) { 
        this.t = t; 
       } 
      } 

      void rethrow() { 
       if (t != null) 
        throw launderThrowable(t); 
      } 
     } 

     RethrowableTask task = new RethrowableTask(); 
     final Thread taskThread = new Thread(task); 
     taskThread.start(); 
     cancelExec.schedule(new Runnable() { 
      public void run() { 
       taskThread.interrupt(); 
      } 
     }, timeout, unit); 
     taskThread.join(unit.toMillis(timeout)); 
     task.rethrow(); 
    } 
} 

Существует утверждение в книге: Даже если задача не отвечает на ответные меры, приуроченный метод запуска все еще может вернуться к своему абоненту.

Мой вопрос: Если я называю этот метод следующим образом:.

timedRun(new Runnable() { 
    @Override 
    public void run() { 
     while(true); 
    } 
}, /* doesn't matter */, /* doesn't matter */); 

Если г не отвечает на запрос прерывания, то taskThread не может быть прервана в этом коде (я прав?) Значит, эта программа, возможно, не реализовала funtionality timed run?

ответ

0

Прерывание в Java - это сотрудничество: оно полагается на то, что прерывается, проверяя прерывание и обращаясь с ним соответствующим образом.

Если у вас есть петля типа while (true);, она не проверяет и не реагирует на прерывание.

Вы могли бы попробовать что-то вроде:

while (!Thread.currentThread().interrupted()); 

Но это «занят ожидание»: он будет держать на проверку прерванный флаг гораздо чаще, чем это может измениться.

Это намного лучше просто положить нить спать до бесконечности:

try { 
    Thread.sleep(Long.MAX_VALUE); 
} catch (InterruptedException e) { 
    // Maybe reset the interrupted flag, if appropriate. 
} 

, так как это не делает ничего, пока поток не фактически прерывается.

Смежные вопросы