2017-02-22 18 views
0

У меня есть потоки, посвященные пользователям в системе, и я хочу, чтобы их можно было остановить в отдельности, я храню идентификатор потока с данными userdata при создании и затем вызываю прерывание? или я могу каким-то образом добавить поток к моим пользовательским объектам и просто называть его myuser.mythread.interrupt(); или это чертовски для магии?Определение идентификатора потока для объекта и прерывания

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

Обновление, не может быть ответом?

if(delete==true) { 
    if (Thread.currentThread().getId() == deleteId) { 
     Thread.currentThread().interrupt(); 
     delete=false; 
    } 
} 

Update

мне удалось найти способ использовать myuser.mythread.interrupt(); Или вроде ..

Я добавил нить в качестве суб класса к классу пользователя и создал метод в классе пользователя для запуска и прерывания, теперь я могу запускать и останавливать темы с

online.get(1).hellos(); 
online.get(1).hellosStop(); 

Вместо того, чтобы создавать ссылку и отслеживать что-либо еще, кроме объектов пользователя.

Update (относительно принятого ответа, используя идентификатор в качестве ссылки я мог бы сделать это таким образом)

public class MyRunnable implements Runnable { 
    private boolean runThread = true; 
    @Override 
    public void run() { 
     try { 
      while (runThread) { 
       if(delete==true) { 
        if (Thread.currentThread().getId() == deleteId) { 
         Thread.currentThread().interrupt(); 
         delete=false; 
        } 
       } 
       Thread.sleep(5); 
      } 
     } 
     catch (InterruptedException e) { 
      // Interrupted, no need to check flag, just exit 
      return; 
     } 
    } 
} 

ответ

1

Вы можете просто хранить Thread ссылку, возможно, в WeakReference так, что поток будет уходить, если он выходит сам по себе.

Но вы также можете проверить поток AtomicBoolean (или volatile boolean) каждый раз, чтобы увидеть, было ли оно прервано, поэтому вам не нужна ссылка на поток.

Обратите внимание, что остановка потоков в Java невозможна без сотрудничества с потоком, который вы хотите остановить. Не имеет значения, используете ли вы interrupt или логическое значение, которое он проверяет, в обоих случаях до потока для проверки этих флагов (interrupt просто устанавливает флаг), а затем выполняет некоторые действия, такие как выход.

Update Образец прерываем класс резьбы:

public class MyRunnable implements Runnable { 
    private final AtomicBoolean stopFlag; 

    public MyRunnable(AtomicBoolean stopFlag) { 
     this.stopFlag = stopFlag; 
    } 

    @Override 
    public void run() { 
     try { // Try/Catch only needed if you use locks/sleep etc. 
      while (!stopFlag.get()) { 
       // Do some work, but remember to check flag often! 
      } 
     } 
     catch (InterruptedException e) { 
      // Interrupted, no need to check flag, just exit 
      return; 
     } 
    } 
} 
+0

У меня тоже было бы 'while (! Thread.interupted() && isActive)' (где isActive - это 'AtomicBoolean', который может быть переключен извне), содержащий основной цикл потока. Но, возможно, OP не может изменить содержимое своих потоков Runnable. –

+0

Хорошо. в настоящее время у меня есть boolean var, который я установил в true или false, чтобы уничтожить потоки или вызвать прерывание, и в этом catch я снова запустил прерывание. который работал, но он контролирует все потоки. Есть ли способ «программно» добавить индикатор переменной для управления потоком? например 'boolean run_ + thread1 = true;'? так что поток работает 'while (run_ + getPassedData) {' –

+0

Просто добавьте поле в свой поток. При создании потоков убедитесь, что его конструктор принимает AtomicBoolean в своем конструкторе. Затем это логическое значение может быть изменено, чтобы сигнализировать о прекращении потока. – john16384

0

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

Технически возможно (для приложения без песочницы) пересекать дерево всех существующих потоков JVM, проверяющих каждый из них. Однако это дорого и не масштабируется. И если вы можете сохранить или передать идентификатор потока, тогда вы должны иметь возможность хранить или передавать ссылку Thread.

Также можно создать свой собственный WeakHashMap<Long, Thread> и использовать его для сопоставления идентификаторов потоков в потоки. Но тот же самый аргумент ...

Вы спрашиваете, если это решение:

if (delete) { 
    if (Thread.currentThread().getId() == deleteId) { 
     Thread.currentThread().interrupt(); 
     delete = false; 
    } 
} 

Нет, это не так. Или, точнее, он будет «работать» только в том случае, когда поток прерывает себя. В других случаях целевой поток не прерывается.


В зависимости от вашего сценария использования, другой способ сделать это может быть использование ExecutionService, а не голые нитей. Методы submit возвращают объект Future, представляющий отправленную задачу. Объект имеет метод cancel(...), который может использоваться для отмены задачи, либо до ее запуска, либо путем прерывания текущего потока.

+0

Хорошо, я думаю, я понимаю. Но что «if (delete)» находится в текущем потоке, поэтому он не ищет и когда глобальное удаление является истинным, любой поток, который имеет тот же самый идентификатор, что и глобальный var deleteId, будет удален? И я нашел способ иметь поток в пользовательском классе, чтобы теперь я мог просто определить класс пользователя по user.get (id) .callStop(); –

+0

Хм, я посмотрю в ExecutionService, чтобы узнать, что это такое. Я делаю много передачи данных, и я читаю, что текущие потоки - лучшая альтернатива для непрерывных задач –