等待特定条件在线程中变为true

时间:2013-05-20 06:12:19

标签: java multithreading

我有一个应用程序向站点发出HTTP请求,然后ant检索响应,检查它们,如果包含特定关键字,则将HTTP请求和响应写入XML文件。此应用程序使用蜘蛛来映射站点的所有URL,然后发送请求(站点地图中的每个URL都被送到发送请求的单独线程)。这样我就无法知道所有请求何时发送。在我要求的最后,我想将XML文件转换为其他格式。因此,为了找出请求何时结束,我使用以下策略:

我将每个请求的时间存储在varible中(当在比变量中的时间晚的时间发送新请求时,varible被更新)。此外,我开始一个线程来监控这个时间,如果当前时间和变量中的时间差异超过1分钟,我知道发送请求已经停止。我为此目的使用以下代码:

class monitorReq implements Runnable{
    Thread t;
    monitorReq(){
        t=new Thread(this);
        t.start();
    }
    public void run(){
        while((new Date().getTime()-last_request.getTime()<60000)){
             try{ 
                 Thread.sleep(30000);//Sleep for 30 secs before checking again
             }
             catch(IOException e){
                 e.printStackTrace(); 
             }
        }
        System.out.println("Last request happened 1 min ago at : "+last_request.toString());
        //call method for conversion of file
    }
}

这种做法是否正确?或者有更好的方法可以实现同样的事情。

2 个答案:

答案 0 :(得分:1)

您目前的做法并不可靠。你将进入竞争条件 - 如果线程正在更新时间&amp;另一个线程正在同时读取它。此外,在多个线程中处理请求也很困难。你假设任务在60秒内完成..

以下是更好的方法。

如果你知道你要提前做出的请求数量,你可以使用CountDownLatch

main() {
   int noOfRequests = ..;
   final CountDownLatch doneSignal = new  CountDownLatch(noOfRequests);

   // spawn threads or use an executor service to perform the downloads
   for(int i = 0;i<noOfRequests;i++) {
      new Thread(new Runnable() {
         public void run() {
            // perform the download
            doneSignal.countDown();
         }
      }).start();
   }

   doneSignal.await();  // This will block till all threads are done.
}

如果您事先不知道请求的数量,那么您可以使用executorService来使用线程池执行下载/处理

main(){

  ExecutorService executor = Executors.newCachedThreadPool();
  while(moreRequests) {
    executor.execute(new Runnable() {
      public void run() {
        // perform processing
      }
    });
  }

  // finished submitting all requests for processing. Wait for completion
  executor.shutDown();
  executor.awaitTermination(Long.MAX_VALUE, TimeUnit.Seconds);

}

答案 1 :(得分:0)

一般说明:

    Java中的
  1. 类应该从Capital Letters

  2. 开始
  3. 您的线程之间似乎没有同步;可能应该同步对last_request的访问

  4. 使用System.currentTimeMillis()可以节省一些对象的创建开销

  5. 吞下像这样的例外不是一个好习惯

  6. <强>答案:

    你这样做是可以接受的。没有太多忙碌的等待,这个想法就像它得到的一样简单。这很好。

    我会考虑将等待时间更改为较低的值;如此少的数据,即使每秒执行此循环也不会占用太多处理能力,并且肯定会从您的应用程序中改善执行时间。