2010-10-07 16 views
6

के साथ सहायता ठीक है, यह एक तरह का दोहरे उद्देश्य का प्रश्न है। मुख्य बात यह है कि मैं इससे दूर जाने की उम्मीद करता हूं बहुसंख्यक का अधिक ज्ञान है। जब मल्टीथ्रेडिंग की बात आती है तो मैं पूरी नौसिखिया हूं, और यह कई धागे में कुछ भी करने का मेरा पहला वास्तविक प्रयास है। दूसरी चीज जो मुझे लेने की उम्मीद है वह होमवर्क के टुकड़े के साथ कुछ मदद है कि मैं मजेदार और सीखने के लिए एक और अधिक जटिल फ्रैंकन-प्रोजेक्ट में बदल रहा हूं। इस प्रश्न के पहले भाग में मैं अपने होमवर्क असाइनमेंट में जिन धागे पर काम कर रहा हूं, उनके लिए मेरी सोच और पद्धति का विस्तार करने जा रहा हूं। अगर मैं कुछ भी कर रहा हूं जो बुरी आदत है, तो तय करने की जरूरत है, जो भी हो, कृपया मुझे बताएं ताकि मैं सीख सकूं। फिर, मैं मल्टीथ्रेडिंग के बारे में व्यावहारिक रूप से कुछ भी नहीं जानता।जावा मल्टीथ्रेडिंग

सबसे पहले, मैं वर्तमान में एक कंप्यूटर विज्ञान पाठ्यक्रम ले रहा हूं, जो इसके बारे में अच्छा है, होमवर्क है जो तकनीक और डेटा संरचनाओं का उपयोग करता है जो मैंने पहले ही सीखा है और इस प्रकार चुनौतीपूर्ण नहीं है। मेरी खोपड़ी से पूरी तरह से ऊबने का प्रयास करने के लिए, मैं एक साधारण परियोजना (एक लिंक्ड लिस्ट और एक क्रमबद्ध लिंक्ड लिस्ट बनाने) की कोशिश कर रहा हूं और इसे एक बहु-थ्रेडेड फ़्रैंकन-प्रोग्राम में बदल सकता हूं। मैं नए तत्वों को एक अलग धागे में जोड़ने के लिए विधि चाहता हूं और एक कतार से इनपुट प्राप्त करता हूं (एक अनुक्रमित सूची के लिए पूरी तरह से जरूरी नहीं है, लेकिन उचित क्रम के लिए अधिक उपयोगी होगा), और आदेशित सूची के लिए मैं एक चाहता हूं अलग थ्रेड जो यह सुनिश्चित करने के लिए सूची को गश्त करेगा कि सभी तत्व क्रम में हैं (उन तरीकों में से एक जिन्हें मैं पूरी नोड्स के रिटर्न संदर्भों को बदलने के लिए अनुमति नहीं देता हूं, जिनमें पूरी तरह से सार्वजनिक डेटा है)। वे दो मुख्य चीजें हैं जिन्हें मैं बनाना चाहता हूं, लेकिन निश्चित रूप से केवल एक चीज नहीं है जिसे मैं कोशिश करना और समझना चाहता हूं। यह मल्टीथ्रेडिंग के बारे में जानने के लिए सिर्फ एक परीक्षण है, इसलिए मैं विशेष रूप से व्यावहारिकता के लिए इस परियोजना को डिजाइन नहीं कर रहा हूं। यदि आप थ्रेड किए जाने के लिए अच्छा प्रोग्रामिंग अभ्यास क्या है या नहीं, इस बारे में कोई टिप्पणी छोड़ना चाहते हैं, तो इसकी अत्यधिक सराहना की जाएगी।

एक कदम के रूप में मैंने हाल ही में लिया था, जिस विचार के लिए स्टैक ओवरव्लो पर एक पोस्ट पढ़ने से प्राप्त किया गया था, मैंने एक मास्टर क्लास बनाया है जिसमें थ्रेड पास हो गए हैं ताकि यह उन्हें रोक सके और अंत में सब कुछ साफ कर सके कार्यक्रम का यह कुछThread.interrupt() के उपयोग के माध्यम से किया जाता है और उस अपवाद के लिए थ्रेड की रन() विधि जांच कर रहा है। हालांकि, मुझे इस विधि के साथ एक समस्या मिली है: लूप जो थ्रेड के माध्यम से चलता है और इंटरप्ट() को कॉल करता है, ज्यादातर बार, वास्तव में नहीं चलता है। यहाँ विधि के लिए कोड है:

public static void stopAllThreads() 
{ 
    boolean stopped = false; 
    while(!stopped) 
    { 
     System.out.println("Stopping all threads"); 

     synchronized(threads) 
     { 
      System.out.println("Threads being stopped: " + threads.size()); 
      for(int i = 0; i < threads.size(); i++) 
      { 
       System.out.println("Stopping: " + threads.get(i)); 
       threads.get(i).interrupt(); 
      } 
      threads.clear(); 
      stopped = true; 
     } 
    } 
} 

यह डिबग करने के लिए प्रयास करते समय, मैं थोड़ी देर के पाश में डाल कोशिश करते हैं और अंत में पाश के लिए चलाने के लिए मजबूर करने के लिए विधि है, लेकिन सभी ऐसा होता है यह outputs "सभी बंद किया जा रहा है धागे "और फिर मैं और कुछ नहीं देखता। मुझे नहीं पता कि यह कोड का एक बुरा तरीका है, या इस कोड के साथ क्या गलत है। इस काम को बनाने के तरीके को समझने में कोई मदद की सराहना की जाती है (यदि आपको कक्षा के अधिक देखने की ज़रूरत है, तो कृपया मुझे बताएं। मुझे वास्तव में पता नहीं है कि आपको क्या देखना है, लेकिन मैं कई कॉपी और पेस्ट नहीं करना चाहता पूरी जावा फाइलें)।

इस समस्या के शीर्ष पर, मैंने यह भी निर्धारित किया है कि मेरे प्रोग्राम को चलाने पर, यह अंतिम पंक्ति तक पहुंच जाएगा और सूची में जोड़ने के लिए संख्याओं की कतार के माध्यम से चलने वाले थ्रेड से पहले थ्रेड को रोकने का प्रयास किया जाएगा, सब कुछ जोड़ना समाप्त हो गया है । कतार में संख्या जोड़ने के बाद सीधे एक टॉस्ट्रिंग विधि के माध्यम से सूची को आउटपुट करने का प्रयास करते समय यह भी एक समस्या है, क्योंकि कुछ भी अभी तक नहीं जोड़ा जाएगा, और इस प्रकार कंसोल पर कुछ भी आउटपुट नहीं होगा। यहाँ मेरी मुख्य विधि है कि क्या हो रहा चीजों के आदेश से पता चलता है (हालांकि मुझे लगता है कि यह कम महत्वपूर्ण है जब सूत्रण के साथ काम कर) है:

public static void main(String[] args) 
{ 
    // always make sure this is the first thing created 
    ActiveThreads bla = new ActiveThreads(); 

    Comparator<Integer> temp = new Comparator<Integer>() 
      { 
       public int compare(Integer i, Integer j) 
       { 
        if(i > j) return 1; 
        if(i < j) return -1; 
        return 0; 
       } 
      }; 
    List<Integer> woogle = new List<Integer>(temp); 

    woogle.add(1); 
    woogle.add(2); 
    woogle.add(3); 
    woogle.add(4); 
    System.out.println(woogle); 

    ActiveThreads.stopAllThreads(); 
} 

अन्त में, यहाँ जो जांच करने के लिए माना जाता है कि मैं बना दिया है कस्टम धागा है कतार तत्वों के लिए है, तो अपने वास्तविक सूची में कतार में सभी तत्वों को जोड़ने:

private class AddThread implements Runnable 
    { 
     public AddThread() 
     { 

     } 

     public void run() 
     { 
      while(running) 
      { 
       synchronized(addQueue) 
       { 
        while(!addQueue.isEmpty()) 
        { 
         System.out.println("Going through queue"); 
         T temp = addQueue.poll(); 
         if(head == null) 
         { 
          head = new Node<T>(); 
          last = head; 
          head.data = temp; 
          largest = temp; 
          smallest = temp; 
         } 
         else 
         { 
          last.next = new Node<T>(); 
          last.next.data = temp; 
          last = last.next; 
          if(mComparator.compare(temp, largest) == 1) 
          { 
           largest = temp; 
          } 
          else if(mComparator.compare(temp, smallest) == -1) 
          { 
           smallest = temp; 
          } 
         } 
         ++size; 
        } 
       } 

       System.out.println("Pausing " + addThread); 
       synchronized(addThread) 
       { 
        pause(200); 
       } 
      } 
     } 

     private void pause(long time) 
     { 
      try 
      { 
       addThread.wait(time); 
      } 
      catch (InterruptedException e) 
      { 
       running = false; 
       addThread.notify(); 
      } 
     } 

     private boolean running = true; 
    } 

अब, निरपेक्ष आखिरी बात मैं के लिए पूछना चाहूँगा बुनियादी प्राइमरों और दिशा निर्देशों और अच्छा बहु सूत्रण के लिए इस तरह से कुछ हैं।मुझे ट्यूटोरियल की अच्छी मात्रा मिली है, लेकिन कुछ चीजें हैं जो लोग ट्यूटोरियल्स में उल्लेख नहीं करते हैं, साथ ही साथ अधिकांश ट्यूटोरियल भी ऐसा ही होते हैं। यदि आप किसी भी अच्छे ट्यूटोरियल के बारे में जानते हैं, तो मैं उनसे लिंक की सराहना करता हूं। यदि मल्टीथ्रेडिंग के लिए कोई अच्छी कोडिंग पद्धतियां हैं, तो इसकी बहुत सराहना की जाएगी। बस आपको लगता है कि किसी भी प्रकार की जानकारी मुझे इस अवधारणा के आस-पास अपने मस्तिष्क को लपेटने में मदद कर सकती है, साथ ही यह सुनिश्चित कर सकती है कि इसे कार्यान्वित करते समय, मैं इसे ऐसे तरीके से करता हूं जो कि बग से कम प्रवण होता है और लोग मुझे बुरा नहीं करेंगे कार्य करती है।

संपादित करें: मैट बी को एक टिप्पणी में डालने के सवालों के जवाब देने के लिए, addThread पूरी तरह से उस धागे का संदर्भ है जो कतार को देखता है जिसमें सूची में जोड़ने के लिए तत्व हैं और उन्हें सूची में डाल दिया जाता है। यह कक्षा के अंदर एक निजी थ्रेड है जिसमें AddThread क्लास (नामों का चालाक उपयोग, एह?) है। थ्रेड का निर्माण इस तरह से किया जाता है जिसे स्टैक ओवरव्लो में एक और प्रश्न में पोस्ट किया गया था।

addThread = new Thread(new AddThread(), "Thread for adding elements"); 
addThread.setPriority(6); 
addThread.start(); 
ActiveThreads.addThread(addThread); 

सभी धागे एक समान तरीके से बनाई गई हैं: यहाँ एक उदाहरण (और यह भी दिखा कोड का एक टुकड़ा क्या addThread है)। जैसा कि मैंने पोस्ट किया था थ्रेड करने के लिए, मैंने समझाया कि ऊपर विस्तार से, लेकिन मैं यहां एक सारांश स्थापित करने की कोशिश करूंगा।

AddThread क्लास एक आंतरिक कक्षा है जो लिंक किए गए सूची वर्ग के निर्माण के समय बनाई जाती है जिसे मैं बनाने की कोशिश कर रहा हूं। यह एक निजी कतार को देखता है जिसमें इसमें तत्व हो सकते हैं या नहीं, और जब ऐसा होता है, तो यह उन तत्वों को लिंक्ड सूची में रखता है। कतारबद्ध सूची की जोड़ने (टी newElt) विधि कहा जाता है जब कतार भी जोड़ा जाता है।

संपादित करें संपादित करें: पूर्ण प्रकटीकरण के हित में, और जो समय लेना चाहते हैं, उनके लिए मैं यहां दो प्रासंगिक जावा फाइलों की पूरी पोस्ट पोस्ट करने जा रहा हूं।

List.java

public class List<T> implements Iterable<T>, Comparable< List<T> > 
{ 
    // you may not change this inner class! 
    class Node<D> 
    { 
     D data; 
     Node<D> next; 
    } 

    public List(Comparator<T> comparator) 
    { 
     mComparator = comparator; 
     head = null; 
     last = null; 
     size = 0; 
     addQueue = new LinkedList<T>(); 

     addThread = new Thread(new AddThread(), "Thread for adding elements"); 
     addThread.setPriority(6); 
     addThread.start(); 
     ActiveThreads.addThread(addThread); 
    } 

    public void add(T newElt) 
    { 
     synchronized(addQueue) 
     { 
      addQueue.add(newElt); 
     } 
    } 

    public T get(int index) 
    { 
     if(index > size) 
      throw new IndexOutOfBoundsException(); 

     Node<T> temp = head; 
     for(int i = 0; i < index; i++) 
     { 
      temp = temp.next; 
     } 
     return temp.data; 
    } 

    public Node<T> lookup(T element) 
    { 
     Node<T> temp = head; 
     for(int i = 0; i < size; i++) 
     { 
      if(temp.data == element) 
       return temp; 
      temp = temp.next; 
     } 
     throw new NoSuchElementException(); 
    } 

    public int size() 
    { 
     return size; 
    } 

    public boolean isEmpty() 
    { 
     return head == null; 
    } 

    public void delete(T element) 
    { 
     throw new UnsupportedOperationException("You must implement this method."); 
    } 

    public void replace(T oldElt, T newElt) 
    { 
     try 
     { 
      Node<T> temp = lookup(oldElt); 
      temp.data = newElt; 
     } 
     catch(NoSuchElementException e) 
     { 
      throw e; 
     } 
    } 

    public T getLargest() 
    { 
     return largest; 
    } 

    public T getSmallest() 
    { 
     return smallest; 
    } 

    public List<T> copy() 
    { 
     throw new UnsupportedOperationException("You must implement this method."); 
    } 

    public String toString() 
    { 
     StringBuffer ret = new StringBuffer(); 
     int i = 0; 
     for(T x : this) 
     { 
      System.out.println("Loop: " + i++); 
      ret.append(x + " "); 
     } 
     return ret.toString(); 
    } 

    public int compareTo(List<T> other) 
    { 
     throw new UnsupportedOperationException("You must implement this method."); 
    } 

    public ListIterator<T> iterator() 
    { 
     return new ListIterator<T>(head); 
    } 

    private class ListIterator<E> implements Iterator<E> 
    { 
     private ListIterator(Node<E> head) 
     { 
      cur = head; 
     } 

     public boolean hasNext() 
     { 
      if(cur == null) 
       return false; 

      System.out.println("Iterator: " + cur.data); 
      return cur.next == null; 
     } 

     @SuppressWarnings("unchecked") 
     public E next() 
     { 
      Node<E> temp = cur; 
      cur = cur.next; 
      return (E)temp.data; 
     } 

     public void remove() 
     { 
      throw new UnsupportedOperationException("You do NOT need to implement " + 
                "this method."); 
     } 

     private Node<E> cur; 
    } 

    private class AddThread implements Runnable 
    { 
     public AddThread() 
     { 

     } 

     public void run() 
     { 
      while(running) 
      { 
       synchronized(addQueue) 
       { 
        while(!addQueue.isEmpty()) 
        { 
         System.out.println("Going through queue"); 
         T temp = addQueue.poll(); 
         if(head == null) 
         { 
          head = new Node<T>(); 
          last = head; 
          head.data = temp; 
          largest = temp; 
          smallest = temp; 
         } 
         else 
         { 
          last.next = new Node<T>(); 
          last.next.data = temp; 
          last = last.next; 
          if(mComparator.compare(temp, largest) == 1) 
          { 
           largest = temp; 
          } 
          else if(mComparator.compare(temp, smallest) == -1) 
          { 
           smallest = temp; 
          } 
         } 
         ++size; 
        } 
       } 

       System.out.println("Pausing " + addThread); 
       synchronized(addThread) 
       { 
        pause(200); 
       } 
      } 
     } 

     private void pause(long time) 
     { 
      try 
      { 
       addThread.wait(time); 
      } 
      catch (InterruptedException e) 
      { 
       running = false; 
       addThread.notify(); 
      } 
     } 

     private volatile boolean running = true; 
    } 

    private Comparator<T> mComparator; 
    private Node<T> head, last; 
    private Thread addThread; 
    // replace this with your own created class later 
    private Queue<T> addQueue; 
    private int size; 
    private T largest, smallest; 
} 

ActiveThreads.java

public class ActiveThreads 
{ 
public ActiveThreads() 
{ 
    if(threads == null) 
    { 
     threads = new ArrayList<Thread>(); 
    } 

    if(threadsMonitor == null) 
    { 
     ThreadsMonitor monitor = new ThreadsMonitor(); 
     Thread thread = new Thread(monitor, "Active Threads Monitor"); 
     thread.setPriority(3); 
     thread.start(); 
     threadsMonitor = thread; 
    } 
} 

public static void stopMonitoring() 
{ 
    synchronized(threadsMonitor) 
    { 
     threadsMonitor.interrupt(); 
    } 
} 

public static void addThread(Thread t) 
{ 
    synchronized(threads) 
    { 
     threads.add(t); 
     System.out.println("Added thread: " + t); 
    } 
} 

public static void addThread(Runnable r, String s) 
{ 
    Thread t = new Thread(r, s); 
    t.start(); 
    addThread(t); 
} 

public static void stopThread(Thread t) 
{ 
    synchronized(threads) 
    { 
     for(int i = 0; i < threads.size(); i++) 
     { 
      if(threads.get(i) == t) 
      { 
       threads.get(i).interrupt(); 
       threads.remove(i); 
      } 
     } 
    } 
} 

public static void stopAllThreads() 
{ 
    boolean stopped = false; 
    while(stopped == false) 
    { 
     System.out.println("Stopping all threads"); 

     synchronized(threads) 
     { 
      System.out.println("Threads being stopped: " + threads.size()); 
      for(int i = 0; i < threads.size(); i++) 
      { 
       System.out.println("Stopping: " + threads.get(i)); 
       threads.get(i).interrupt(); 
      } 
      threads.clear(); 
      stopped = true; 
     } 
    } 
} 

private static ArrayList<Thread> threads = null; 
private static Thread threadsMonitor = null; 

private class ThreadsMonitor implements Runnable 
{ 
    public ThreadsMonitor() 
    { 

    } 

    public void run() 
    { 
     while(true) 
     { 
      synchronized(threads) 
      { 
       for(int i = 0; i < threads.size(); i++) 
       { 
        if(!threads.get(i).isAlive()) 
        { 
         threads.get(i).interrupt(); 
         threads.remove(i); 
        } 

        synchronized(threadsMonitor) 
        { 
         try 
         { 
          threadsMonitor.wait(5000); 
         } 
         catch(InterruptedException e) 
         { 
          threadsMonitor.interrupted(); 
          return; 
         } 
        } 
       } 
      } 
     } 
    } 
} 
} 
+6

बहुत लंबा! :) – rkg

+0

हे, इसके लिए मेरी माफ़ी। मुझे वास्तव में पता नहीं है कि इसके लिए पोस्ट करने के लिए क्या आवश्यक है या नहीं, और दुर्भाग्यवश, मेरे विवरण बहुत लंबे समय तक समाप्त हो गए। – Freezerburn

+0

हालांकि आपको अपने प्रयास की सराहना करना है! –

उत्तर

0

समस्या मिली: एक नेस्टेड सिंक्रनाइज़ ब्लॉक था जो ब्लॉक के सबसे निचले हिस्से में प्रतीक्षा() को कॉल करने के लिए कॉल में चला गया था, बिना थ्रेड्स के ऐरेलिस्ट पर लॉक जारी किए।

synchronized(threads) 
      { 
       for(int i = 0; i < threads.size(); i++) 
       { 
        if(!threads.get(i).isAlive()) 
        { 
         threads.get(i).interrupt(); 
         threads.remove(i); 
        } 
       } 
      } 

      synchronized(threadsMonitor) 
      { 
       try 
       { 
        threadsMonitor.wait(5000); 
       } 
       catch(InterruptedException e) 
       { 
        threadsMonitor.interrupted(); 
        return; 
       } 

समस्या थी, धागे के तुल्यकालन के अंदर threadsMonitor के तुल्यकालन को हटाने के रूप में नीचे देखा समस्या ठीक होती है,। (मैं एक चंचल जानवर स्वरूपण मुद्दों, प्रतिलिपि + पेस्ट है के लिए माफी माँगता)

  synchronized(threadsMonitor) 
      { 
       try 
       { 
        threadsMonitor.wait(5000); 
       } 
       catch(InterruptedException e) 
       { 
        threadsMonitor.interrupted(); 
        return; 
       } 
      } 

synchronized(threads) 
       { 
       for(int i = 0; i < threads.size(); i++) 
       { 
        if(!threads.get(i).isAlive()) 
        { 
         threads.get(i).interrupt(); 
         threads.remove(i); 
        } 
       } 
      } 
     } 

बहु सूत्रण संसाधन के लिए माइक क्यू के लिए धन्यवाद। मेरे पास अभी तक इसके साथ बहुत कुछ करने का समय नहीं है, लेकिन मैं निश्चित रूप से एक नज़र डाल रहा हूं और आशा करता हूं कि बहुत कुछ सीख रहा हूं। मैं धागे को रोकने के अलावा इस मुद्दे के साथ एक अलग प्रश्न भी बनाउंगा।

5

यह पूरी तस्वीर लेकिन कुछ सामान्य अंक और भी अधिक सामान्य सुझाव को देखने के लिए मुश्किल है।

यह डिबग करने के लिए प्रयास करते समय, मैं में डाल जबकि पाश कोशिश करते हैं और अंत में पाश, के लिए चलाने के लिए विधि मजबूर करने के लिए, लेकिन सभी ऐसा होता है "रोकना सभी धागे" तो मैं इसे आउटपुट है और बाकी

कुछ भी ऐसा इसलिए है क्योंकि एक और धागा एक sychronized ब्लॉक में बैठा है एक ही ताला का उपयोग करने और उसे चलाना कोड को रोकने है कभी नहीं। पता लगाने का सबसे आसान तरीका यह है कि इसे डीबगर में चलाने के लिए और प्रोग्राम को रोकें/तोड़ें जब आपको लगता है कि यह अटक जा सकता है। आप धागे का निरीक्षण करने और अपने राज्य की जांच करने में सक्षम होना चाहिए। ब्लॉक की स्थिति की तलाश करें।

while(!stopped)stopAllThreads में अनावश्यक है क्योंकि यह कभी लूप नहीं कर सकता है।

AddThread में आपके पास इस

private boolean running = true; 

करने के लिए एक बूलियन का उपयोग करते समय एक को रोकने ध्वज (जो मुझे लगता है कि आप क्या हासिल करने की कोशिश कर रहे हैं) और कहा कि बंद झंडा किसी अन्य के द्वारा एक धागा द्वारा सर्वेक्षण में शामिल है, लेकिन सेट किया गया है के रूप में तो आपको इसे volatile बनाना होगा। जावा मल्टीथ्रेडिंग कोडिंग का एक पूरा क्षेत्र है जो डेटा दृश्यता से संबंधित है और volatile सहीता सुनिश्चित करने के लिए उपयोग किए जाने वाले टूल में से एक है।

अक्सर प्रोग्राम "सही" बहुभाषी तर्क के बिना "अधिकतर समय में ठीक" काम करते हैं। लेकिन वे टूट गए हैं और सबसे अधिक संभावना असुविधाजनक समय पर टूट जाएंगे (आमतौर पर जैसे ही ग्राहक इसे पकड़ लेता है)! (यदि आपको याद है कि मेरे उत्तर में एक बात पिछली वाक्य याद है: डी)

जितना आप कर सकते हैं java.util.concurrent पैकेज का लाभ उठाएं। हालांकि मूलभूत सिद्धांतों को भी समझना बहुत महत्वपूर्ण है, इस पैकेज में बहुत ही चालाक लोगों द्वारा डिजाइन की गई बहुत उपयोगी संरचनाएं हैं जो कई आम सहमति समस्याओं को हल करती हैं।

Java Concurrent In Practice पढ़ें। विषय के लिए यह वर्णन कर रहा है (संभावित रूप से बहुत सूखा) यह अवधारणाओं को बहुत से उदाहरणों के साथ सुलभ तरीके से समझाता है। यह उसी समूह द्वारा लिखा गया था जिसने java.util.concurrent पैकेज पर काम किया था।

अपने अनुभव से मुझे लगता है कि समवर्ती कार्यक्रमों में डेटा की "दृश्यता" जावा थ्रेड प्रोग्रामिंग का सबसे महत्वपूर्ण और कम से कम समझा हिस्सा है। यदि आप अपना सिर गोल कर सकते हैं कि आप अपने रास्ते पर अच्छे होंगे। JCIP इससे आपकी सहायता कर सकता है।

आशा है कि उपर्युक्त मदद और शुभकामनाएँ!

संपादित करें: इस के साथ अपने अतिरिक्त कोड में एक और समस्या चित्तीदार निर्माण

for(int i = 0; i < threads.size(); i++) 
{ 
    if(!threads.get(i).isAlive()) 
    { 
     threads.get(i).interrupt(); 
     threads.remove(i); 
    } 
} 

इस प्रकार की सूची का एक अनुक्रमित स्कैन के अंदर एक निकालें() करने से अपेक्षा के अनुरूप काम नहीं करेगा क्योंकि निकालें() के साथ हस्तक्षेप सूची में अन्य वस्तुओं की अनुक्रमणिका (सभी बाद की वस्तुओं को एक सूचकांक में स्थानांतरित किया जाता है)।

+0

ओह ठीक है! मैं आमतौर पर उस तरह की चीज़ के बारे में अधिक जागरूक हूं। मुझे इंगित करने और मुझे बाद में गंजा जाने से बचाने के लिए धन्यवाद। – Freezerburn

+0

एक अस्थिर क्षेत्र बनाने के बजाय परमाणु बूलियन (http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/atomic/AtomicBoolean.html) का उपयोग करने के लिए बेहतर :) यह जावा 1.5 में पहुंचा/5.0। –

संबंधित मुद्दे