从不同的线程填充数组

时间:2011-03-08 21:13:43

标签: java multithreading static

我正在尝试编写一个非常简单的程序,它创建了几个线程来将并发请求发送到特定的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]; }
}  

}

4 个答案:

答案 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
  }

}