用于URL的groovy线程

用于URL的groovy线程,groovy,multithreading,Groovy,Multithreading,我编写了使用线程测试URL的逻辑。 这适用于URL数量较少且需要检查的URL超过400个的情况 类URL扩展线程{ def有效 定义url URL( url ) { this.url = url } void run() { try { def connection = url.toURL().openConnection() connection.setConnectTimeout(10000) if(connection.respon

我编写了使用线程测试URL的逻辑。 这适用于URL数量较少且需要检查的URL超过400个的情况

类URL扩展线程{
def有效 定义url

URL( url ) {
    this.url = url
}

void run() {
    try {
        def connection = url.toURL().openConnection()
    connection.setConnectTimeout(10000)
        if(connection.responseCode == 200 ){
            valid = Boolean.TRUE
        }else{
            valid = Boolean.FALSE
        }
    } catch ( Exception e ) {
        valid = Boolean.FALSE
    }
}
}



    def threads = [];
    urls.each { ur ->
       def reader = new URL(ur)
       reader.start()
       threads.add(reader);
    }

     while (threads.size() > 0) {
       for(int i =0; i < threads.size();i++) {
         def tr = threads.get(i);
            if (!tr.isAlive()) {
                if(tr.valid == true){
                  threads.remove(i);
                  i--; 
            }else{
              threads.remove(i);
              i--;
            }
        }
     }
URL(URL){
this.url=url
}
无效运行(){
试一试{
def connection=url.toURL().openConnection()
connection.setConnectTimeout(10000)
if(connection.responseCode==200){
valid=Boolean.TRUE
}否则{
valid=Boolean.FALSE
}
}捕获(例外e){
valid=Boolean.FALSE
}
}
}
def线程=[];
URL.each{ur->
def读卡器=新URL(ur)
reader.start()
添加(读卡器);
}
while(threads.size()>0){
对于(int i=0;i
谁能告诉我如何优化逻辑,我哪里出了问题


提前感谢。

您考虑过使用java.util.concurrent helpers吗?它允许在更高的抽象级别上进行多线程编程。有一个简单的接口可以在线程池中运行并行任务,这比只为n个任务创建n个线程并期待最好的结果更容易管理和调整

然后,您的代码最终看起来像这样,您可以在其中调优nThreads,直到获得最佳性能:

import java.util.concurrent.*

def nThreads = 1000
def pool = Executors.newFixedThreadPool(nThreads)
urls.each { url ->
    pool.submit(url)
}
def timeout = 60
pool.awaitTermination(timeout, TimeUnit.SECONDS)

您考虑过使用java.util.concurrent helpers吗?它允许在更高的抽象级别上进行多线程编程。有一个简单的接口,可以在线程池中运行并行任务,这比为n个任务创建n个线程并希望达到最佳效果更容易管理和调整

然后,您的代码最终看起来像这样,您可以在其中调优nThreads,直到获得最佳性能:

import java.util.concurrent.*

def nThreads = 1000
def pool = Executors.newFixedThreadPool(nThreads)
urls.each { url ->
    pool.submit(url)
}
def timeout = 60
pool.awaitTermination(timeout, TimeUnit.SECONDS)

根据ataylor的建议和您的代码,我得出以下结论:

import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit

class MyURL implements Runnable {
  def valid
  def url

  void run() {
    try {
      url.toURL().openConnection().with {
        connectTimeout = 10000
        if( responseCode == 200  ) {
          valid = true
        }
        else {
          valid = false
        }
        disconnect()
      }
    }
    catch( e ) {
      valid = false
    }
  }
}

// A list of URLs to check
def urls = [ 'http://www.google.com',
             'http://stackoverflow.com/questions/2720325/groovy-thread-for-urls',
             'http://www.nonexistanturlfortesting.co.ch/whatever' ]

// How many threads to kick off
def nThreads = 3
def pool = Executors.newFixedThreadPool( nThreads )

// Construct a list of the URL objects we're running, submitted to the pool
def results = urls.inject( [] ) { list, url ->
  def u = new MyURL( url:url )
  pool.submit u
  list << u
}

// Wait for the poolclose when all threads are completed
def timeout = 10
pool.shutdown()
pool.awaitTermination( timeout, TimeUnit.SECONDS )

// Print our results
results.each {
  println "$it.url : $it.valid"
}

我将类名更改为MyURL,而不是您原来的URL,因为当您开始使用java.net.URL类时,使用ataylor的建议和您的代码,它很可能会避免问题,我做到了:

import java.util.concurrent.Executors
import java.util.concurrent.TimeUnit

class MyURL implements Runnable {
  def valid
  def url

  void run() {
    try {
      url.toURL().openConnection().with {
        connectTimeout = 10000
        if( responseCode == 200  ) {
          valid = true
        }
        else {
          valid = false
        }
        disconnect()
      }
    }
    catch( e ) {
      valid = false
    }
  }
}

// A list of URLs to check
def urls = [ 'http://www.google.com',
             'http://stackoverflow.com/questions/2720325/groovy-thread-for-urls',
             'http://www.nonexistanturlfortesting.co.ch/whatever' ]

// How many threads to kick off
def nThreads = 3
def pool = Executors.newFixedThreadPool( nThreads )

// Construct a list of the URL objects we're running, submitted to the pool
def results = urls.inject( [] ) { list, url ->
  def u = new MyURL( url:url )
  pool.submit u
  list << u
}

// Wait for the poolclose when all threads are completed
def timeout = 10
pool.shutdown()
pool.awaitTermination( timeout, TimeUnit.SECONDS )

// Print our results
results.each {
  println "$it.url : $it.valid"
}

我将类名改为MyURL,而不是您原来的URL,因为当您开始使用java.net.URL类时,它更可能避免出现问题

谢谢您,但我的不好。如何从循环调用URL类而不是从池中调用URL.submit(URL)。请用循环中的一些代码向我解释。谢谢请修复代码的格式,以便我可以看到您正在尝试执行的操作。谢谢您,但我的错误。如何从循环中调用URL类而不是池。提交(URL)。请用循环中的一些代码向我解释一下。谢谢请修复代码的格式,这样我就可以看到你在做什么。谢谢tim yates,但我发现大多数URL都显示为null,而不是true或false。尽管所有null URL都有效且有效。你能告诉我为什么会出现问题吗。我创建了500个URL来运行。它一定是错误的设置超时。将超时变量设置为higherthanks很多。是的,我将超时从10增加到60,适用于500-700之间的URL。在我的数据库中,我有2700个URL,当一次尝试此操作时,失败并给出错误结果。您能告诉我可以提供多少超时吗?我们是否需要在URL类中为fir增加connectTimeout第一部分,要永远等待,请将timeout更改为Long.MAX_值,并将TimeUnit.SECONDS更改为TimeUnit.NANOSECONDS。第二部分的答案可能是“这取决于”嗨,蒂姆,你能告诉我其他选择吗。我的浏览器在使用Long.MAX_值循环2700个URL时挂起。谢谢蒂姆·耶茨,但我发现大多数URL都显示nul我改为true或false。虽然所有空URL都有效且有效。您能告诉我为什么会中断吗?我创建了500个URL要运行。它一定是超时了。将超时变量设置为HigherHanks很多。是的,我将超时从10增加到60,适用于500-700之间的URL。在我的数据库中,我有2700个URL,一次尝试此操作时,是否为f出现问题并给出错误的结果。您能告诉我可以给出多少超时吗?我们是否需要在URL类中增加connectTimeout作为第一部分,以便永远等待,将timeout更改为Long.MAX_值,并将TimeUnit.SECONDS更改为TimeUnit.NANOSECONDS。第二部分的答案可能是“这取决于”Hi tim,您能告诉我吗我的浏览器在2700个URL循环中使用Long.MAX_值时挂起。