简体   繁体   English

Java MultiThread等到子线程死亡

[英]Java MultiThread wait until child threads die

I have following Java code: 我有以下Java代码:

import java.io.*;
class Global{
public static int a = 0 ;
public static int b = 0 ;
}
public class Example{
public static void main(String args[]) {
    try {
        FileOutputStream fos = new FileOutputStream("1.dat");
        DataOutputStream dos = new DataOutputStream(fos);

        for (int i = 0; i < 20000; i++) {
            dos.writeInt(i);
        }
        dos.close();

        FileOutputStream fos1 = new FileOutputStream("2.dat");
        DataOutputStream dos1 = new DataOutputStream(fos1);

        for (int i = 20000; i < 40000; i++) {
            dos1.writeInt(i);
        }
        dos1.close();

        Exampless.createArray(20000); //static method call to set the static arr variable
        Exampless ex1 = new Exampless("1.dat"); //found number of matches in file
        Exampless ex2 = new Exampless("2.dat");
        Thread t1 = new Thread(ex1);
        Thread t2 = new Thread(ex2);
        t1.start();
        t1.join();
        t2.start();
        t2.join();
        System.out.println("No. of Matches: " + (Global.a + Global.b ));

    } catch (Exception e) {
        System.err.println("Error: " + e.getMessage());
    }
}
}

class Exampless implements Runnable {

public static int[] arr = new int[20000];
public String _name;

public Exampless(String name) {
    this._name = name;
}

static void createArray(int z) {
    for (int i = z; i < z + 20000; i++) {
        arr[i - z] = i;
    }
}

public void run() {
    try {
        int cnt = 0;
        FileInputStream fin = new FileInputStream(_name);
        DataInputStream din = new DataInputStream(fin);
        for (int i = 0; i < 20000; i++) {
            int c = din.readInt();
            if (c == arr[i]) {
                cnt++;
            }
        }
        System.out.println("File name: " + _name + " No. of Matches: " + cnt);
        if(_name == "1.dat")
            Global.a = cnt ;
        else if(_name == "2.dat")
            Global.b = cnt ;
    } catch (Exception e) {
        System.err.println("Error: " + e.getMessage());
    }
}

}

There I am trying to run Exampless classes run method parallely. 我试图在其中运行示例类, run并行方式run方法。 However, I want to make main thread wait until child thread finishes, which I have done using join . 但是,我想让主线程等到子线程完成,这是我使用join完成的。 But, it makes execution of thread one after another. 但是,它使线程的执行一个接一个。 Can anybody help me how to solve this ? 有人可以帮我解决这个问题吗? Another point is that, I want to share a variable (named as cnt which found number of matches in files)among two threads which I have done using Global class to found total number of matches. 另一点是,我想在两个线程中共享一个变量(名为cnt,该变量在文件中找到了匹配的数目),这两个线程是我使用Global类完成的,以找到匹配的总数。 Is there any other nice solution ? 还有其他好的解决方案吗?

t1.join() waits until t1 is done, so you need to invert the 2 lines: t1.join()等待t1完成,因此您需要反转两行:

t1.start();
t2.start();
t1.join();
t2.join();

However, you would be better off using the high level concurrency package, and typically an ExecutorService : 但是,最好使用高级并发程序包,通常使用ExecutorService

ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(ex1);
executor.submit(ex2);
executor.shutdown();

Your next question: 您的下一个问题:

I want to share a variable (named as cnt which found number of matches in files)among two threads which I have done using Global class to found total number of matches. 我想在两个线程中共享一个变量(命名为cnt,在文件中找到匹配的数目),这两个线程已使用Global类完成以找到匹配的总数。 Is there any other nice solution ? 还有其他好的解决方案吗?

What you are doing is not thread safe, unless those variables are volatile. 您正在执行的操作不是线程安全的,除非这些变量是易失的。 If they are not, it is possible that your print in your main will not print the latest value of those variables. 如果不是,则可能是您的主打印机中的打印内容不会打印这些变量的最新值。

A better solution would be to have Exampless implement Callable instead of Runnable, in which case you can return a value. 更好的解决方案是让Examples实现Callable而不是Runnable,在这种情况下,您可以返回一个值。

You can then retrieve the value from the future returned by the executor: 然后,您可以从执行程序返回的Future中检索值:

Future<Integer> future1 = executor.submit(ex1);
Future<Integer> future2 = executor.submit(ex2);

count1 = future1.get();
count2 = future2.get();

ps: you need to add error handling code around the future.get() calls ps:您需要在future.get()调用周围添加错误处理代码

Have you tried starting both threads first before joining? 您是否尝试过在加入之前先启动两个线程?

    t1.start();
    t2.start();
    t1.join();
    t2.join();

而不是在上一个线程完成之后再启动下一个线程,而是使用CountDownLatch监视线程的状态

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM