import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;class Worker extends   Thread {
 private CountDownLatch threadsSignal;

  private BlockingQueue<URL> queue;
  public Worker(BlockingQueue<URL> q,CountDownLatch threadsSignal){
  this.queue = q;
  this.threadsSignal = threadsSignal;   }
  mycheckurl1 n= new mycheckurl1();
     public void run()  {
  for (URL url = queue.poll(); url != null; url = queue.poll()){
 int retcode =n.checkURL(url);
  System.out.println(Thread.currentThread().getName()+"线程"+retcode+"连接地址"+ url);

  }
  threadsSignal.countDown();
  System.out.println(Thread.currentThread().getName() + "结束. 还有" +                     threadsSignal.getCount() + " 个线程");
     }
 
  
    
}public class show { public static void main(String[] args) throws MalformedURLException, InterruptedException {
String [] d=readFileByLines("D:/SYSTEM/桌面/新建文件夹 (2)/wenzhou61.164.110.250.txt");


new mycheckurl1().cc(d);
System.out.println("sdf");

 }
public void cc(String[] d) throws InterruptedException, MalformedURLException{
 int threadNum = 100;
 
         CountDownLatch threadSignal = new CountDownLatch(threadNum);// 初始化
         BlockingQueue<URL> urls =new ArrayBlockingQueue<URL>(20000);         for (int i=1;i<d.length-2;i++){
         if(d[i]!=null){
          urls.put(new URL(d[i]));
          }else{
    break;
         }
         }
     for(int i=0;i<100;i++){
          Thread t = new Worker(urls,threadSignal);              t.start();
   }   threadSignal.await();
  

}
public static String[] readFileByLines(String fileName){
   File file = new File(fileName);
   String [] kk=new String[50000];
   BufferedReader reader = null;
   try {
  //  System.out.println("以行为单位读取文件内容,一次读一整行:");
    reader = new BufferedReader(new FileReader(file));
    String tempString = null;
    int line = 1;
    //一次读入一行,直到读入null为文件结束
    while ((tempString = reader.readLine()) != null){
     //显示行号
 //    System.out.println("line " + line + ": " + tempString);
     kk[line]=tempString;
     line++;
    }
    reader.close();
   } catch (IOException e) {
    e.printStackTrace();
   } finally {
    if (reader != null){
     try {
      reader.close();
     } catch (IOException e1) {
     }
    }
   }
   return kk;}

public  int checkURL(URL url)  {

HttpURLConnection huc;
    try {
huc =  ( HttpURLConnection )  url.openConnection ();
huc.setConnectTimeout(1000*60*2);
   huc.setRequestMethod ("GET");  huc.connect () ;
int    code = huc.getResponseCode (  ) ; //能链接上才会有所谓的返回值
return code;
} catch (IOException e) {
System.out.println("time out");


return 0;

}

}

解决方案 »

  1.   


    运行了后一直不能结束。
     System.out.println("sdf"); 也不能输出
      

  2.   

    原因应该是你的threadsSignal.countDown();线程数不够多,所以threadSignal.await();就会一直阻塞
      

  3.   


    恩,
    Thread-26线程200连接地址http://61.164.110.10/v/2011-11/22/2011-1122CVNC123114394989218174.mp4
    Thread-26结束. 还有7 个线程
    Thread-76线程200连接地址http://61.164.110.10/v/2011-11/22/2011-1122CVNC123015101210616679.mp4
    Thread-76结束. 还有6 个线程
    Thread-84线程200连接地址http://61.164.110.10/v/2011-11/22/2011-1122CVNC123016381477317279.mp4
    Thread-84结束. 还有5 个线程
    Thread-28线程200连接地址http://61.164.110.10/v/2011-11/22/2011-1122CVNA123008491036215967_7369.mp4
    Thread-28结束. 还有4 个线程
    这样就一直卡着
      

  4.   

    像是同步没有做好
    ArrayBlockingQueue没有实现线程安全
    用多线程直接操作很容易出问题
      

  5.   

    CountDownLatch threadSignal = new CountDownLatch(threadNum);// 初始化
    这里初始化为100,那么要保证执行100次threadsSignal.countDown();
    否则threadSignal.await();会一直阻塞
    还要注意一点就是,
    for (URL url = queue.poll(); url != null; url = queue.poll()){
    当queue是BlockingQueue,也就是阻塞队列,当queue没有数据,也就是队列为空时,poll会造成线程等待,也就是线程阻塞,所以你虽然生成了100线程,但是
    for (int i=1;i<d.length-2;i++){
             if(d[i]!=null){
              urls.put(new URL(d[i]));
    加入队列的数据如果不到100,那么就会造成for (URL url = queue.poll(); url != null; url = queue.poll()){阻塞,所以threadsSignal.countDown();也就没有被执行,所以主线程的threadSignal.await();一直阻塞,所以程序就不会结束
      

  6.   

    数据不到100也能结束,因为你用的是poll,只有put和take才会发生队列阻塞
    而且你的线程也有100个,所以按理应该会执行100次threadsSignal.countDown();
    这样主线程的threadSignal.await();就不该阻塞的
    难道中间有某些线程出异常了?
    是不是有些线程可能一直连接不上,要等2分钟发生timeout
      

  7.   


    import java.io.IOException;
    import java.net.HttpURLConnection;
    import java.net.SocketTimeoutException;
    import java.net.URL;
    import java.util.concurrent.BlockingQueue;
    import java.util.concurrent.LinkedBlockingQueue;public class BookChecker {    public static void main(final java.lang.String[] args) throws Exception {
            BlockingQueue<URL> urls = new LinkedBlockingQueue<URL>();
            urls.add(new URL("http://www.baidu.com"));
            urls.add(new URL("http://www.google.com"));
            urls.add(new URL("http://www.google.com/dasfad"));
            urls.add(new URL("http://www.jgoodies.com"));        CheckURLWorker w1 = new CheckURLWorker("w1",urls);
            CheckURLWorker w2 = new CheckURLWorker("w2",urls);
            new Thread(w1).start();
            new Thread(w2).start();
        }    private static class CheckURLWorker implements Runnable {
            private BlockingQueue<URL> queue;
            private String name;
            public CheckURLWorker(String name,BlockingQueue<URL> q){
                this.name = name;
                this.queue = q;
            }        @Override public void run() {
                for (URL url = queue.poll(); url != null; url = queue.poll()) {
                    try{
                        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                      
                        connection.setRequestMethod("GET");
                        connection.connect();
                        int code = connection.getResponseCode();
                        connection.disconnect();
                        System.out.printf("[%s]%s:%d%n",name,url.toString(),code);
                    } catch (SocketTimeoutException e) {
                        System.out.printf("[%s]%s:%d%n",name,url.toString(),-1);
                    } catch (IOException e) {
                        System.err.println(e);
                    }
                }
            }
        }
    }好像是这个有问题  我urls加入5000条记录,运行很长时间也没结束
      

  8.   


    要等2分钟发生timeout 我去掉了也这样
      

  9.   

    拿LZ的代码跑了一遍,5000条记录,没出现卡死情况
    LZ的环境有问题?
      

  10.   

    这不是运气好不好的问题,程序上除了我说了,除非有些线程被异常终止而每能执行threadsSignal.countDown();才会导致threadSignal.await();阻塞,而你没有捕捉异常,如果真有异常发生,应该会被打印到控制台,我这边没有异常发生。
    为了保证threadsSignal.countDown();一定会被执行,你可以把它放到try finally里
    如果不想长时间等待,可以再设置一个线程或者用Timer,设置一定时间后System.exit(-1)退出程序就可以了