2012-03-30 30 views
10

Sorun açıklaması: -bekleyin: Java

Adım 1: ana iş parçacığı de kullanıcıdan girdi FILE_NAME atın.

Adım 2: Bu dosyada 10 işlem gerçekleştirin (örn. Numaralar, sayılar vb. Sayın) ve tüm bu 10 işlem septat iş parçacığında olmalıdır. Yani 10 çocuk dişi olmalı.

Adım 3: Ana iş parçacığı, tüm alt iş parçacıkları tamamlanana kadar bekler.

Adım 4: Yazdırma sonuçları.

Yaptıklarımı: -

Ben 3 iş parçacığı ile bir örnek kod yaptı. Dosya işlem kodunu yanınızdan istemiyorum.

public class ThreadTest { 
    // This is object to synchronize on. 
    private static final Object waitObject = ThreadTest.class; 
    // Your boolean. 
    private static boolean boolValue = false; 

    public final Result result = new Result(); 

    public static void main(String[] args) { 
     final ThreadTest mytest = new ThreadTest(); 

     System.out.println("main started"); 

     new Thread(new Runnable() { 

      public void run() { 
       System.out.println("Inside thread"); 

       //Int initialiser 
       new Thread(new Runnable() { 

        public void run() { 
         System.out.println("Setting integer value"); 
         mytest.result.setIntValue(346635); 
         System.out.println("Integer value seted"); 
         try { 
          Thread.sleep(1000); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
       }).start(); 

       //String initialiser 
       new Thread(new Runnable() { 

        public void run() { 
         System.out.println("Setting string value"); 
         mytest.result.setStringValue("Hello hi"); 
         System.out.println("String value seted"); 
         try { 
          Thread.sleep(1000); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
       }).start(); 

       //Boolean initialiser 
       new Thread(new Runnable() { 

        public void run() { 
         System.out.println("Setting boolean value"); 
         mytest.result.setBoolValue(true); 
         System.out.println("Boolean value seted"); 
         try { 
          Thread.sleep(1000); 
         } catch (InterruptedException e) { 
          // TODO Auto-generated catch block 
          e.printStackTrace(); 
         } 
        } 
       }).start(); 

       System.out.println("Thread is finished"); 

       //Notify to main thread 
       synchronized (ThreadTest.waitObject) { 
        ThreadTest.boolValue = true; 
        ThreadTest.waitObject.notifyAll(); 
       }    
      } 
     }).start(); 

     try { 
      synchronized (ThreadTest.waitObject) { 
       while (!ThreadTest.boolValue) { 
        ThreadTest.waitObject.wait(); 
       } 
      } 
     } catch (InterruptedException ie) { 
      ie.printStackTrace(); 
     } 

     System.out.println("main finished"); 
     System.out.println("Result is : " + mytest.result.toString()); 
    } 
} 

Sorun: -

Benim Yukarıdaki kod doğru cevap vermiyor. Bunu nasıl yapabilirim?

Alternatif çözümler:

CountDownLatch sınıfı aynı işi yapar. Ama bu sınıfı kullanmak istemiyorum.

this similar solution'a baktım ve yalnızca Thread konuları kullanmak istiyorum.

+8

Thread .join() yöntemini okuyun. – shift66

+0

Ödev ise öyleyse bir dahaki sefere çöp kutusuna atmalısınız. – Voo

cevap

29

Sen yapabilirsiniz: Konunun bitinceye kadar bekleyin ve tam o sırada devam edecektir

Thread t = new Thread() { 
    public void run() { 
     System.out.println("text"); 
     // other complex code 
    } 
}; 
t.start(); 
t.join(); 

Bu şekilde. Şunları yapabilirsiniz join birden çok iş parçacığı:

for (Thread thread : threads) { 
    thread.join(); 
} 
+0

Birleştirme() yalnızca çözümdür mü? Veya verdiğim örnekte bazı kodları değiştirerek bunu yapabilir miyim? – Andy

+0

Bu en iyi, en doğru ve tavsiye edilen çözümdür. Muhtemelen bunu başka bir şekilde yapabilirsiniz, ama sizi uyarıyorum - iş parçacığıyla uğraşmak can sıkıcıdır ve olabildiğince çok kitaplık işlevlerinde bulunur. –

+1

Bunu denedim ancak bir iş parçacığı, çalışmaya başlamak için diğer iş parçacığı bekler. Tüm iş parçacıkları aynı anda çalışmıyor. Tüm konuları başlatmak istiyorum ve hepsi bitene kadar beklerim. –

10

İlk Executors framework bakarak tavsiye ve sonra CompletionService içine bakmak istiyorum.

ExecutorService executor = Executors.newFixedThreadPool(maxThreadsToUse); 
CompletionService completion = new ExecutorCompletionService(executor); 
for (each sub task) { 
    completion.submit(new SomeTaskYouCreate()) 
} 
// wait for all tasks to complete. 
for (int i = 0; i < numberOfSubTasks; ++i) { 
    completion.take(); // will block until the next sub task has completed. 
} 
executor.shutdown(); 
+0

completionservice belirttiğiniz için teşekkür ederiz .. geçen 1 gün boyunca baktım :) – xyz

1

bu yaklaşım pek çok yolu vardır:

Sonra böyle bir şey yazabilirsiniz. CountDownLatch düşünün:

import java.util.concurrent.CountDownLatch; 

public class WorkerTest { 
    final int NUM_JOBS = 3; 
    final CountDownLatch countDownLatch = new CountDownLatch(NUM_JOBS); 
    final Object mutex = new Object(); 
    int workData = 0; 

    public static void main(String[] args) throws Exception { 
     WorkerTest workerTest = new WorkerTest(); 
     workerTest.go(); 
     workerTest.awaitAndReportData(); 
    } 

    private void go() { 
     for (int i = 0; i < NUM_JOBS; i++) { 
      final int fI = i; 
      Thread t = new Thread() { 
       public void run() { 
        synchronized(mutex) { 
         workData++; 
        } 
        try { 
         Thread.sleep(fI * 1000); 
        } catch (InterruptedException e) { 
         e.printStackTrace(); 
        } 
        countDownLatch.countDown(); 
       } 
      }; 
      t.start(); 
     } 
    } 

    private void awaitAndReportData() throws InterruptedException { 
     countDownLatch.await(); 
     synchronized(mutex) { 
      System.out.println("All workers done. workData=" + workData); 
     } 
    } 
} 
1

Sen java.util.concurrent den CountDownLatch seçmek isteyebilirsiniz. Javadocs Gönderen:

operasyonların kümesi tamamlandığında diğer konuları gerçekleştirildiği kadar bir veya birden fazla iş parçacığı bekleyin sağlayan bir senkronizasyon yardım.

örnek kod:

import java.util.concurrent.CountDownLatch; 

public class Test { 
    private final ChildThread[] children; 
    private final CountDownLatch latch; 

    public Test() { 
     this.children = new ChildThread[4]; 
     this.latch = new CountDownLatch(children.length); 
     children[0] = new ChildThread(latch, "Task 1"); 
     children[1] = new ChildThread(latch, "Task 2"); 
     children[2] = new ChildThread(latch, "Task 3"); 
     children[3] = new ChildThread(latch, "Task 4"); 
    } 

    public void run() { 
     startChildThreads(); 
     waitForChildThreadsToComplete(); 
    } 

    private void startChildThreads() { 
     Thread[] threads = new Thread[children.length]; 

     for (int i = 0; i < threads.length; i++) { 
      ChildThread child = children[i]; 
      threads[i] = new Thread(child); 
      threads[i].start(); 
     } 
    } 

    private void waitForChildThreadsToComplete() { 
     try { 
      latch.await(); 
      System.out.println("All child threads have completed."); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 

    private class ChildThread implements Runnable { 
     private final String name; 
     private final CountDownLatch latch; 

     protected ChildThread(CountDownLatch latch, String name) { 
      this.latch = latch; 
      this.name = name; 
     } 

     @Override 
     public void run() { 
      try { 
       // Implementation 
       System.out.println(name + " has completed."); 
      } finally { 
       latch.countDown(); 
      } 
     } 
    } 

    public static void main(String[] args) { 
     Test test = new Test(); 
     test.run(); 
    } 
} 

Çıktı:

Görev 1 tamamlamıştır. Görev 4 tamamlandı. Görev 3 tamamlandı. Görev 2 tamamlandı. Tüm çocuk konuları tamamlandı. Java 8 çok daha iyi bir yaklaşım olarak

2

parallelStream kullanmaktır()

Not: Tam olarak bu arka plan görevleri yaptıklarını görmek için çok daha kolaydır.

public static void main(String[] args) { 
    Stream.<Runnable>of(
     () -> mytest.result.setIntValue(346635), 
     () -> mytest.result.setStringValue("Hello hi"), 
     () -> mytest.result.setBoolValue(true)) 
     .parallel() 
     .forEach(Runnable::run); 

    System.out.println("main finished"); 
    System.out.println("Result is : " + mytest.result.toString()); 
} 

Hata ayıklama bilgilerini ve uykuyu çıkardım çünkü bunlar sonucu değiştirmiyorlar.