2016-03-19 19 views
0

Bir run() ileten iş parçacıklarından çağrılan bir yöntem var. Ben geçti ve bekleme()notifyAll iş parçacığı uyanıyor.

bir şartı olarak kullanmak kaç Konuları hesaplamak için bir yineleyici yapmak Ben çalıştırmak konuları()


public void testMethod(Object x) throws InterruptedException { 
    synchronized (x) { 
     while(threadsWaiting <= 5) { 
      threadsWaiting++; 
      System.out.println(x.getName() + " waiting " + 
        " | Threads waiting: " + threadsWaiting); 
      x.wait(); 
     } 
     x.notifyAll(); 
     System.out.println(x.getName() + " passed " + 
       " | Threads waiting: " + threadsWaiting); 
    } 
} 

çalıştırıldığında aşağıdaki kod

Örnek çıkışı:

Thread 0 is created 
Thread 1 is created 
Thread 2 is created 
Thread 3 is created 
Thread 4 is created 
Thread 5 is created 
Thread 6 is created 
Thread 7 is created 
Thread 8 is created 
Thread 9 is created 
Thread 10 is created 
Thread 11 is created 
Thread 12 is created 
Thread 13 is created 
Thread 14 is created 
Thread 15 is created 
Thread 16 is created 
Thread 17 is created 
Thread 18 is created 
Thread 19 is created 
Thread 20 is created 
Thread 16 waiting | Threads waiting: 1 
Thread 9 waiting | Threads waiting: 2 
Thread 5 waiting | Threads waiting: 3 
Thread 14 waiting | Threads waiting: 4 
Thread 0 waiting | Threads waiting: 5 
Thread 13 waiting | Threads waiting: 6 
Thread 15 passed | Threads waiting: 6 
Thread 10 passed | Threads waiting: 6 
Thread 4 passed | Threads waiting: 6 
Thread 12 passed | Threads waiting: 6 
Thread 1 passed | Threads waiting: 6 
Thread 20 passed | Threads waiting: 6 
Thread 11 passed | Threads waiting: 6 
Thread 18 passed | Threads waiting: 6 
Thread 3 passed | Threads waiting: 6 
Thread 2 passed | Threads waiting: 6 
Thread 17 passed | Threads waiting: 6 
Thread 8 passed | Threads waiting: 6 
Thread 6 passed | Threads waiting: 6 
Thread 19 passed | Threads waiting: 6 
Thread 7 passed | Threads waiting: 6 

Eğer geçemiyor bekleyen bütün evreleri Görüldüğü gibi.

Bu yalnızca şu şekilde çalışır: 10 x nesne geçiriyorum. 5 tanesi bekle(), diğer 5 baskısı. Yazdırıldıktan sonra x.notifyAll() çağrılır, ancak artık 'Bitir' yazdırılmaz.

NotifyAll()? I çağırdıktan sonra neden boştalar? Bitirdi Keşke notifyAll diyoruz sonra bile 5 kez basılır çünkü onlar boşta olduğunu biliyorum()

+0

Sorununuzu yeniden üretemiyor. IDE'imde ve [ideone] 'da (http://ideone.com/ODvI0w) 5 'Waiting' ve 10' Finished' i alıyorum. – Nier

+0

Her iş parçacığındaki x'iniz farklı ** örnek ** var mı? Çünkü eğer x'imi statik olmayandan statik olmayana değiştirirsem, sorunuzda bahsettiğiniz gibi 5 'Bekliyor 've 5' Bitirdi 'olurum. – Nier

+0

@Nier Evet, her bir iş parçacığındaki farklı ifadeler, 'ClassName.method (bu)' gibi onu iletirken, '' run '' (method '' method '' sorusu içinde olan yöntem ve 'bu' x –

cevap

0

Tam çalışma örneği aşkın 5.

public class Notify { 

    public static void main(String[] args) { 
     Object obj = new Object(); 
     for (int i = 1; i <= 10; i++) { 
      Runnable myThread = new MyThread(i, obj); 
      new Thread(myThread).start(); 
     } 
    } 

    public static class MyThread implements Runnable{ 

     static final int MAX_THREAD = 5; 
     int id; 

     Object x; 

     public MyThread(int id, Object x) { 
      this.id = id; 
      this.x = x; 
     } 

     @Override 
     public void run() { 
      if(id > MAX_THREAD){ 
       try { 
        synchronized (x) { 
         x.wait();      
        } 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
      //Process something 
      try { 
       Thread.sleep(2000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      System.out.println("Process Thread : " + id); 
      synchronized (x) { 
       x.notifyAll();    
      } 
     } 

    } 

} 
+0

Tam olarak aynı yapıyorum ... Eşzamanlı bir x.wait() var ve sonra x.notifyAll yapıyorum ama senkronize edilmiyor ve bir fark yaratmasa bile denedim . Tek fark, tüm bunları() çalışmasında() çalıştırdığımda() çalıştırdığımda, (x) nesnesinin kendisinin bir örneğini (bu) iletmesini sağlamak için başka bir yönteme gidiyorum. Ama bu tam olarak aynı. Neden benim işim olmadı? –

+0

Konularınızı tam olarak nasıl başlattığınız? –

+0

@GordonFreemanTurtle Eğer 'this' nesnesini x olarak geçirirseniz, senkronize ettiğinizizin farklı monitörlerde kilitlendiği farklı örneklerdir. Bunun yerine this.getClass() 'i geçmeyi düşünün. – Nier

0

O mümkündür iplik kimliği ise bekleyip 10 konuları oluşturmak Diğer tüm thread'lar wait olarak adlandırılmadan önce notifyAll çağrılıyor. Bu olursa, diğer mesajlar tekrar bilgilendirilene kadar monitörde beklemeye son verecektir.

Bekleme ve bildirim yerine, java.util.concurrent ürününe bakmalısınız. CountDownLatch ile başlarım. De ki threadsWaiting 4. olan

+0

İş parçacıkları, diğer dizilerden önce x.notifyAll() 'ifadesini nasıl çağırır? X.wait()'? Hepsi "senkronize" blokta. – Nier

+0

Bazı parçacıklar diğerleri bitmeden başlayamaz. Ayrıca, sayı değişkeni ile neler olup bittiğini netleştirmeyin. Bu iş parçacığı arasında bir tür paylaşılan değişken mi? – Bill

+0

@Bill Soruyu güncelledim. İplik üretmeyi ne zaman durduracağını belirlemek için kullanırım. –

0
while(threadsWaiting <= 5) { 
     threadsWaiting++; 
     System.out.println(x.getName() + " waiting " + 
       " | Threads waiting: " + threadsWaiting); 
     x.wait(); 
    } 

Biz <= 5 testi geçmek, bu yüzden while döngü girin. threadsWaiting'u 5'e artırdık, sonra wait'u arayın. Ama biz threadsWaiting için 5 veya daha fazla olmak için bekliyoruz ve zaten var. Yani zaten olan bir şeyi bekliyoruz.

Zaten gerçekleşmiş olan bir şeyin beklenmesi, en yaygın olarak kullanılan notify/wait kötüye kullanımıdır.

+0

Neden "threadWaiting" 5 veya daha fazla olmak için bekleyin? Ben bu konuların beklemesini beklemek istiyorum 'bildir', artık işlere gerek yok 'bekle ' –

+0

@GordonFreemanTurtle Ne dediğini anlamıyorum. Konularınızın beklediğini düşündüğünüz koşul nedir? –

+0

Bekledikleri için, bu yönteme devam etmelerini ve –

İlgili konular