【发布时间】:2011-06-21 13:38:14
【问题描述】:
我是多线程编程的新手。使用 join 方法时出现意外行为。有时两个线程给出相同的结果,有时只显示一个结果,有时显示正确的结果。我做错了什么?
public class Client {
public static void main(String args[]) throws Exception {
String model = args[0];
String property = args[1];
String parameters = args[2];
String wsdlPaths = args[3];
int numServices = Integer.parseInt(args[4]);
String[] parameter;
getParameters(parameters, parameter);
String[] wsdl;
getWSDL(wsdlPaths, wsdl);
Thread[] t = new Thread[numServices];
ClientHelper[] nch = new ClientHelper[numServices];
TestStub[] stub = new TestStub[numServices];
TestStub.Experiment[] request = new TestStub.Experiment[numServices];
TestStub.ExperimentResponse[] response = new TestStub.ExperimentResponse[numServices];
for (int i = 0; i < numServices; i++) {
stub[i] = new TestStub(wsdl[i]);
request[i] = new TestStub.Experiment();
request[i].setArgs0(model);
request[i].setArgs1(property);
request[i].setArgs2(parameter[i]);
nch[i] = new ClientHelper(stub[i], request[i]);
t[i] = new Thread(nch[i]);
t[i].start(); // When I moved this statement to the next loop just before the join method, the program behaved like a single threaded program and was working correctly.
}
for (int i = 0; i < numServices; i++) {
try {
t[i].join();
} catch (InterruptedException e) {
}
System.out.println(t[i].getName());
response[i] = nch[i].response;
System.out.println("Response " + i + " : " + response[i].get_return());
}
}
}
public class ClientHelper implements Runnable {
TestStub stub;
TestStub.Experiment request;
TestStub.ExperimentResponse response;
public ClientHelper(TestStub stub, TestStub.Experiment request){
this.stub = stub;
this.request = request;
}
public void run() {
try {
response = stub.Experiment(request);
}
catch (Exception e) {
}
}
}
【问题讨论】:
-
你有没有机会解决你的问题,并创建一个更小的测试用例?我看到的第一件事是您的一个线程可能会抛出异常,而您永远看不到它,因此会出现意外行为。在你的空 catch 块中添加一个 print 语句。
-
那不是您正在运行的代码。例如,这不会编译:
String[] wsdl; getWSDL(wsdlPaths, wsdl);。请贴出真实代码。 -
@Jon 是的,这不是真正的代码,我正在运行,我试图尽可能多地剥离代码。真正的代码需要一些模型和属性文件以及可以执行这些文件的 Web 服务。所以你将无法运行它。我的主要问题是
for (int i=0;i<n;i++) { thread[i].start(); } for (int i=0;i<n;i++) { thread[i].join(); //output variable set by thread[i]. }在不同的运行中,打印出来的变量是不同的。有时它们是相同的,有时只打印其中一个,有时根本不打印。 -
因此,将您的代码简化为可以演示问题的内容但会编译。否则,您很可能已经解决了问题。见tinyurl.com/so-hints。我的猜测是你有一些你不想要的共享状态,但如果你不能给我们任何现实的代码,我们就无法判断。
标签: java multithreading