2012-03-30 32 views
10

Vấn đề: -Chờ cho đến khi đề con hoàn thành: Java Mô tả

Bước 1: Hãy FILE_NAME đầu vào từ người dùng tại thread chính.

Bước 2: Thực hiện 10 thao tác trên tệp đó (ví dụ: đếm ký tự, đếm số, vv ..) và tất cả 10 thao tác đó phải nằm trong chuỗi đề tài. Nó có nghĩa là phải có 10 chủ đề con.

Bước 3: Chủ đề chính đợi cho đến khi tất cả các chuỗi con đó hoàn tất.

Bước 4: Kết quả in.

Những gì tôi đã làm: -

tôi đã làm một mẫu mã với 3 chủ đề. Tôi không muốn mã hoạt động của tệp từ phía bạn.

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()); 
    } 
} 

Vấn đề: -

mã trên của tôi không đưa ra câu trả lời đúng. Làm thế nào tôi có thể làm điều đó?

giải pháp thay thế:

lớp CountDownLatch cũng làm như vậy. Nhưng tôi không muốn sử dụng lớp đó.

Tôi đã xem this similar solution và tôi chỉ muốn sử dụng các phương thức Chỉ chủ đề.

+8

đọc về phương thức .join() của Chủ đề. – shift66

+0

Nếu đó là bài tập về nhà, bạn nên đổ rác như vậy vào lần sau. – Voo

Trả lời

29

Bạn có thể làm:

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

Bằng cách này bạn sẽ đợi cho đến khi kết thúc chủ đề và chỉ sau đó tiếp tục. Bạn có thể join nhiều chủ đề:

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

Tham gia() chỉ là giải pháp? Hoặc bằng cách sửa đổi một số mã trong ví dụ của tôi, tôi có thể làm điều đó? – Andy

+0

Đây là giải pháp tốt nhất, chính xác nhất và được khuyến khích. Có lẽ bạn có thể làm điều đó theo cách khác, nhưng tôi cảnh báo bạn - đối phó với các chủ đề là tẻ nhạt và cư trú với các hàm thư viện nhiều nhất có thể. –

+1

Tôi đã thử điều này nhưng một luồng đang đợi chuỗi khác để bắt đầu thực thi. Tất cả các chủ đề không thực thi trong cùng một thời điểm. Tôi muốn bắt đầu tất cả các chủ đề và chờ đợi cho đến khi tất cả chúng được hoàn thành. –

10

tôi sẽ khuyên bạn nên nhìn vào khuôn khổ Executors đầu tiên, và sau đó nhìn vào CompletionService.

Sau đó, bạn có thể viết một cái gì đó như thế này:

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

cảm ơn bạn đã chỉ định completionservice..Was tìm kiếm nó từ 1 ngày qua :) – xyz

1

Có rất nhiều cách để tiếp cận này. Hãy xem xét CountDownLatch:

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

Bạn có thể muốn chọn CountDownLatch từ java.util.concurrent. Từ JavaDocs:

Hỗ trợ đồng bộ hóa cho phép một hoặc nhiều luồng chờ đến khi hoàn thành một số thao tác trong các chủ đề khác.

Mẫu mã:

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(); 
    } 
} 

Output:

Nhiệm vụ 1 đã hoàn thành. Nhiệm vụ 4 đã hoàn thành. Nhiệm vụ 3 đã hoàn thành. Nhiệm vụ 2 đã hoàn thành. Tất cả các chủ đề con đã hoàn thành.

2

Trong Java 8 một cách tiếp cận tốt hơn là sử dụng parallelStream()

Lưu ý: nó là xa dễ dàng hơn để xem chính xác những gì các nhiệm vụ nền đang làm.

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()); 
} 

Tôi đã lấy thông tin gỡ rối và chế độ ngủ vì những thông tin này không làm thay đổi kết quả.

Các vấn đề liên quan