2011-02-28 20 views
9

Çalışma zamanı hata mesajına göre, Özel Durum aşağıdaki satırda gerçekleşir; Java "ConcurrentModificationException" yineleme çalışırken çalışma zamanı hatası .next()


VirusData

VirusData v = iteratorVirusDB.next(); 
bir kurucu ve veritabanı gibi virüslerin her biri hakkında bilgi ihtiva eden bir aşırı kurucu bir sınıf;

  • Yaylı VName
  • Yaylı vDefinition

(xLength gruplar halinde ayrılır) dizgecikli tanımı LCS belirteçleri ile

  • Array

    • Array Aşırı
    • şamandıra Depolayabilir burada

      Iterator<VirusData> iteratorVirusDB = virusDB.iterator(); 
      

      VirusDB ve tip <VirusData> ArrayList: aşağıda gösterildiği gibi bir not ile tip <VirusData> arasında


    iteratorVirusDB,() VirusDB bir .iterator olan Virüs nesneleri (bu noktada isim ve def) böylece bunları daha sonra kullanabilirim.

    ArrayList <VirusData> virusDB = new ArrayList<VirusData>(); 
    

    Ve ile sonlandırmak için hata yukarıdaki tüm açıkladı kullanan bu yöntemde oluşur: Gerçekten konusunda bazı yardım ve tavsiye ile yapabilirdi

    private void selectDabataseMouseClicked(java.awt.event.MouseEvent evt) { 
        while(iteratorVirusDB.hasNext()) { 
         VirusData v = iteratorVirusDB.next();    //ERROR LINE 
         String vSig = v.signature;        
         v.tokens = tokenize.raw(vSig, true, tLength); 
         ... 
        } 
        ... 
    } 
    

    Programın başarılı bir şekilde çalışmasını sağlamak için bu probleme yaklaşmak. Körük, tam StackTrace:

    run: 
    Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException 
         at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372) 
         at java.util.AbstractList$Itr.next(AbstractList.java:343) 
         at project_clean.Main.selectDabataseMouseClicked(Main.java:275) 
         at project_clean.Main.access$100(Main.java:11) 
         at project_clean.Main$2.mouseClicked(Main.java:76) 
         at java.awt.AWTEventMulticaster.mouseClicked(AWTEventMulticaster.java:253) 
         at java.awt.Component.processMouseEvent(Component.java:6270) 
         at javax.swing.JComponent.processMouseEvent(JComponent.java:3267) 
         at java.awt.Component.processEvent(Component.java:6032) 
         at java.awt.Container.processEvent(Container.java:2041) 
         at java.awt.Component.dispatchEventImpl(Component.java:4630) 
         at java.awt.Container.dispatchEventImpl(Container.java:2099) 
         at java.awt.Component.dispatchEvent(Component.java:4460) 
         at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4577) 
         at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4247) 
         at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4168) 
         at java.awt.Container.dispatchEventImpl(Container.java:2085) 
         at java.awt.Window.dispatchEventImpl(Window.java:2478) 
         at java.awt.Component.dispatchEvent(Component.java:4460) 
         at java.awt.EventQueue.dispatchEvent(EventQueue.java:599) 
         at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269) 
         at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184) 
         at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174) 
         at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169) 
         at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161) 
         at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 
    
  • +1

    'ArrayList' öğesini yapısal olarak değiştirdiğinizde yineleyici geçersiz olur. Bir yineleyiciyi üyeler arasında sınıf durumu olarak kaydetme şüphelidir. Bunu neden yapıyorsun? – rlibby

    +0

    Sadece bir ConcurrentModificationException ile ilgili bir soruya cevap verdim ... http://stackoverflow.com/questions/5145135/java-util-concurrentmodificationexception-on-arraylist/5145156#5145156 –

    +0

    Eh, gerçekten nasıl yineleyiciler çalışıyorum bilmiyorum Yakın zamanda var olduklarını keşfettiler, bu yüzden deneme yanılma yoluyla çok fazla öğreniyorum. Yani eğer doğru bir şekilde anlarsam, bunu yapmamalıyım 'Iterator iteratorVirusDB = virusDB.iterator(); '? Ama sonra böyle bir şeyi nasıl yineleyebilirim; VirusData v = virusDB.iterator(). Sonraki(); '? Öneriniz için teşekkürler – Carlos

    cevap

    11

    bariz açıklama size çağrılar arasında virusDB değiştirilmiş olması. Bir yineleyici kullanarak yinelenirken, vektörü değiştirmemelisiniz (Iterator/ListIterator yöntemlerinden hariç).

    Örneğin

    , bir iş parçacığı bir değiştirmek için genellikle izin değildir: ConcurrentModificationException belgelenmesi itibaren

    import java.util.*; 
    
    class VirusData { 
    } 
    
    public class Test { 
    
        public static void main(String[] args) { 
    
         List<VirusData> list = new ArrayList<VirusData>() {{ 
          add(new VirusData()); 
          add(new VirusData()); 
          add(new VirusData()); 
         }}; 
    
         Iterator<VirusData> iterator = list.iterator(); 
    
         iterator.next(); 
    
         list.remove(0); 
         VirusData s = iterator.next(); 
        } 
    } 
    

    :

    Bu kod pasajı hep bir ConcurrentModificationException atacağım Başka bir iş parçacığı ise yinelenen koleksiyon. Genel olarak, iterasyonun sonuçları bu koşullar altında tanımlanmamıştır.Bazı yineleyici uygulamaları (JRE tarafından sağlanan tüm genel amaçlı toplama uygulamalarınınkileri de dahil olmak üzere), bu davranış algılanırsa bu özel durumu atmayı seçebilir. Bunu gerçekleştiren yineleyiciler, hızlı ve temiz bir şekilde başarısız oldukları için başarısız hızlı yineleyiciler olarak bilinir; ancak, gelecekteki belirsiz bir zamanda rastgele, deterministik olmayan davranışları riske sokarlar.

    Bu özel durumun, her zaman bir nesnenin farklı bir iş parçacığı tarafından aynı anda değiştirildiğini göstermediğini unutmayın. Tek bir iş parçacığı, bir nesnenin sözleşmesini ihlal eden bir dizi yöntem çağrısı yayınlarsa, nesne bu özel durumu atabilir. Örneğin, bir iş parçacığı bir koleksiyonunu doğrudan yineleyici bir yineleyici ile yineleme sırasında değiştirirse, yineleyici bu özel durumu atar.

    niyetinizi tüm veri tabanı üzerinden yöntemi her çağrıldığında yineleme ise ben de sizin önermek

    de üzerinde yineleme sırasında değiştirerek zaman eşzamanlı modifikasyon durum oluşur
    private void selectDabataseMouseClicked(java.awt.event.MouseEvent evt) { 
        Iterator<VirusData> iteratorVirusDB = virusDB.iterator(); 
        while(iteratorVirusDB.hasNext()) { 
         VirusData v = iteratorVirusDB.next(); 
         String vSig = v.signature;        
    
    +0

    ancak bir program sürekli bu durumda bir listeyi değiştirirse, nasıl bir yineleme olabilir? – Carlos

    +1

    Bir indeksi kullanabilirsiniz, 'i ',' i 'yourList.size()' ve 'next()' ile 'yourList.get (i)' ile 'hasNext' değiştirin. – aioobe

    +0

    Çok teşekkürler aioobe, cevabınızda öne koyduğunuz öneri işe yaradı. Ancak şimdi şaşkınım, v.tokens = tokenize.raw (vSig, true, tLength) yaptığımda, * (önerinizde atıfta bulunulmadı) *, dizideki bir öğeyi değiştirerek kuralı ihlal etmiyor. Veya "değişiklik" terimi yalnızca bir öğe eklerken/kaldırırken yalnızca kelimeler ihlal edildiğinde "boyut" koleksiyonuna uygulanır. – Carlos

    0

    Aynı zaman. Bu nedenle, listeyi değiştiriyorsanız kodunuzu kontrol edin ve üzerinde yineleme yaparken gerçekleşir.

    İlgili konular