2016-06-02 3 views
-1

Извините, если возникнут непонятные вопросыМожет ли эта ссылка в run() ссылаться на объект Thread при реализации Runnable?

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

вот мой код

public class MainProgram { 
    //some global static variable 
    static List<Thread> threadList = new LinkedList<Thread>(); 
    public void main() throws IOException { 
     ServerSocket serverSocket; 
     serverSocket = new ServerSocket(1234); 
     while(true){ 
      if(Shutdown_Handler.shutdown==true){ 
       //wait for all other thread close/terminate 
       return 
      } 
      Socket s = serverSocket.accept(); 
      ClientThread x = new ClientThread(s); 
      Thread y = new Thread(x); 
      threadList.add(y); 
      y.start(); 

     } 
    } 
} 

когда Shutdown_Handler.shutdown == истинный основной будет проверять, если он цепочек является null. Проблема в том, что я не знаю, как сделать поток удаленным из списка. Как то, что я искал, для обычного объекта, можно создать метод, как этот

public class someObject { 
    public static void delete(){ 
     if(list.size = null) return; 
     list.remove(this); 
    } 
} 

Однако, в случае потока, класс реализации Runnable так this ссылка на объект, а не поток сохраняется в списке

+0

Если я правильно понял, вы можете использовать ExecutorService с Futures, которые доступны на Java. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html – Mamun

+0

Если вы хотите манипулировать списком в нескольких потоках, вы должны сделать его потокобезопасным, используя Collections.synchronizedList (..) или что-то в этом роде. – waltersu

+0

Вы не можете ссылаться * на этот * в статическом методе. Если вы хотите получить текущий поток в классе Runnable, используйте Thread.currentThread(). – waltersu

ответ

1

Я бы рекомендовал использовать HashMap вместо List. Ключами могут быть имя потока (например, Thread.getName()), а значениями будут темы Threads.

Map<String, Thread> threadMap = new HashMap<String, Thread>(); 

Вы также должны создать эту карту в качестве synchronizedMap (используя Collections.synchronizedMap(...))

Map<String, Thread> synchronizedMap = Collections.synchronizedMap(threadMap); 

Теперь, когда вы создаете тему, вы передаете эту HashMap в его конструктор и нить может содержать ссылку на Это. Поэтому, когда поток вот-вот завершится, он может удалить себя из HashMap, используя собственное имя Thread в качестве ключа для удаления.

1

Предполагая, что ClientThread является Runnable, основной код:

public class ClientThread implements Runnable { 
    public void run() { 
     // do stuff 
     MainProgram.threadList.remove(Thread.currentThread()); 
    } 
} 

Однако это имеет несколько проблем:

  1. Там будут несколько потоков, выполняющих операции в списке без надлежащей синхронизации. Это неверно, и вы можете получить прерывистые сбои, если вы это сделаете.

  2. Если run() удаляет нить из списка в блоке finally, поток, который прерывается аномально, не может быть удален.

  3. Плохой дизайн для использования глобального статического электричества. И худший дизайн, чтобы разоблачить его как голую (не-частную) переменную.

  4. A HashSet<Thread> был бы более эффективным, если число потоков может быть большим.

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