我正在尝试编写一个非常简单的程序,它创建了几个线程来将并发请求发送到特定的URL。我测量并存储响应时间。我遇到的问题是,尽管我将响应时间数组创建为静态和最终,但我存储在此数组中的值仅在我生成一个生成的线程时才存在。一旦我离开循环并进入主线程,数组就为空(包含0个值)。所以我的代码片段中的总和始终为零。我意识到我的错误可能是一个非常基本的错误,但不幸的是我无法在网上找到类似的主题。你能指点我正确的方向吗?谢谢。
public class MyClass {
static final long[] respTimes = new long[l];
public static void sendRequest() {...}
public static void main(String[] args) throws Exception {
for(int i=0; i<l; i++) {
new Thread("" + i) {
public void run() {
long startTime = System.nanoTime();
sendRequest();
long estimatedTime = System.nanoTime() - startTime;
respTimes[i] = estimatedTime;
}
}.start();
}
for(int i=0; i<l; i++) { sum += respTimes[i]; }
}
}
答案 0 :(得分:7)
这不是问题。您的问题是您在有机会生成结果之前打印出结果。这样做:
Thread [] theThreads = new Thread[10];
for (...) {
theThreads[i] = new Thread() { ... }.start();
}
// now make sure all the threads are done
for (...) {
// this waits for the thread to finish
theThreads[i].join();
}
// now print things out
答案 1 :(得分:0)
:O静态最终数组?那不好的
尝试通过构造函数将数组传递给线程,并在主线程
中创建它http://en.wikipedia.org/wiki/Final_(Java)
最终变量只能分配一次。
与常量的值不同,最终变量的值在编译时不一定是已知的。
答案 2 :(得分:0)
您可能正在经历竞争状况。 for循环在任何线程实际启动和/或完成之前完成。
如果您使用的是JDK 1.5或更高版本,请查看使用java.lang.concurrent类。他们使这些类型的线程连接操作非常容易。
HTH
答案 3 :(得分:0)
因为我对静态方法有一种临床厌恶:P和组织代码的事情(还注意到你没有处理发送方法产生的任何异常)
public class MultiClient
{
private long[] responseTimes = null;
private Throwable[] errors = null;
public MultiClient(int count)
{
responseTimes = new long[count];
errors = new Throwable[count];
}
protected void sendRequestWrapper(int index)
{
long startTime = System.nanoTime();
try
{
//original send request
sendRequest();
}
// optionally you may put a catch() here to process errors
catch(Throwable t)
{
errors[index] = t;
}
finally
{
//this will guarantee response times filled up even in case of
//sendRequest raising an exception
responseTimes[index] = System.nanoTime() - startTime;
}
}
public void doStuff()
{
Thread[] threads = new Thread[count];
//separete create thread calls
for(int i = 0; i < threads.length; i++)
{
threads[i] = new Worker(i);
}
//... from start calls
for(int i = 0; i < threads.length; i++)
{
threads[i].start();
}
// wait till all threads are done
for(int i = 0; i < threads.length; i++)
{
threads[i].join();
}
}
private class Worker extends Thread
{
private int index = -1;
public Worker(int index)
{
super("worker "+index);
this.index = index;
}
public void run()
{
MultiClient.this.sendRequestWrapper(index);
}
}
public long[] getResponseTimes(){ return responeTimes; }
public Throwable[] getErrors(){ return errors; }
public boolean sendFailed(int indeX){ return errors[index] != null; }
public static void main(String[] args)
{
int count = ...; // get count from somewhere (cmd line, hard coded etc.)
MultiClient multiClient = new MultiClient(count); //create an array filler
multiClient.doStuff(); //this will block till all the threads are done
long[] responseTimes = multiClient.getResponseTimes();
//do whatever you want with the response times
}
}