我有以下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());
}
}
}
我试图并行运行Exampless类run
方法。但是,我想让主线程等到子线程完成,这是我使用join
完成的。但是,它一个接一个地执行线程。任何人都可以帮我解决这个问题吗?另一点是,我想在两个线程中共享一个变量(命名为cnt,它找到文件中的匹配数),我使用Global类来完成匹配的总数。还有其他不错的解决方案吗?
答案 0 :(得分:4)
t1.join()
等到t1完成,所以你需要反转2行:
t1.start();
t2.start();
t1.join();
t2.join();
但是,最好使用高级并发包,通常是ExecutorService:
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.submit(ex1);
executor.submit(ex2);
executor.shutdown();
你的下一个问题:
我想在两个线程中共享一个变量(命名为cnt,它找到文件中的匹配数),我使用Global类来完成匹配的总数。还有其他不错的解决方案吗?
您所做的不是线程安全的,除非这些变量是易失性的。如果不是,则主体中的打印可能无法打印这些变量的最新值。
更好的解决方案是让Exampless实现Callable而不是Runnable,在这种情况下,您可以返回一个值。
然后,您可以从执行者返回的未来中检索值:
Future<Integer> future1 = executor.submit(ex1);
Future<Integer> future2 = executor.submit(ex2);
count1 = future1.get();
count2 = future2.get();
ps:您需要在future.get()
调用
答案 1 :(得分:1)
你有没有尝试在加入之前先启动两个线程?
t1.start();
t2.start();
t1.join();
t2.join();
答案 2 :(得分:1)
而不是在上一个完成之后启动下一个Thread,而是使用CountDownLatch来监视线程的状态