簡體   English   中英

Java MultiThread等到子線程死亡

[英]Java MultiThread wait until child threads die

我有以下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());
    }
}

}

我試圖在其中運行示例類, run並行方式run方法。 但是,我想讓主線程等到子線程完成,這是我使用join完成的。 但是,它使線程的執行一個接一個。 有人可以幫我解決這個問題嗎? 另一點是,我想在兩個線程中共享一個變量(名為cnt,該變量在文件中找到了匹配的數目),這兩個線程是我使用Global類完成的,以找到匹配的總數。 還有其他好的解決方案嗎?

t1.join()等待t1完成,因此您需要反轉兩行:

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

但是,最好使用高級並發程序包,通常使用ExecutorService

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

您的下一個問題:

我想在兩個線程中共享一個變量(命名為cnt,在文件中找到匹配的數目),這兩個線程已使用Global類完成以找到匹配的總數。 還有其他好的解決方案嗎?

您正在執行的操作不是線程安全的,除非這些變量是易失的。 如果不是,則可能是您的主打印機中的打印內容不會打印這些變量的最新值。

更好的解決方案是讓Examples實現Callable而不是Runnable,在這種情況下,您可以返回一個值。

然后,您可以從執行程序返回的Future中檢索值:

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

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

ps:您需要在future.get()調用周圍添加錯誤處理代碼

您是否嘗試過在加入之前先啟動兩個線程?

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

而不是在上一個線程完成之后再啟動下一個線程,而是使用CountDownLatch監視線程的狀態

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM