等到子线程完成:Java

问题描述 : –

第1步:在主线程中从用户处输入FILE_NAME。

步骤2:对该文件执行10次操作(即计数字符,计数行等),所有这10个操作必须是隔离线程。 这意味着必须有10个子线程。

第3步:主线程等待所有子线程完成。

第4步:打印结果。

我做了什么 :-

我做了3个线程的示例代码。 我不希望你的文件操作代码。

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

问题: –

我上面的代码没有给出正确的答案。 我怎样才能做到这一点?

替代解决方案:

CountDownLatch类也是如此。 但我不想使用那个class级。

我看了这个类似的解决方案 ,我想只使用Thread的方法。

你可以做:

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

这样你就会等到线程结束然后再继续。 您可以join多个线程:

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

我建议先查看Executors框架,然后查看CompletionService 。

然后你可以写这样的东西:

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

在Java 8中,更好的方法是使用parallelStream()

注意:确切地看到这些后台任务正在做什么要容易得多。

 public static void main(String[] args) { Stream.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()); } 

我取出了调试信息和睡眠,因为这些不会改变结果。

有很多方法可以解决这个问题。 考虑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); } } } 

您可能希望从java.util.concurrent选择CountDownLatch 。 来自JavaDocs:

允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助。

示例代码:

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

输出:

任务1已完成。 任务4已经完成。 任务3已经完成。 任务2已完成。 所有子线程都已完成。