import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
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>();
        String [] d=readFileByLines("C:/Documents and Settings/Owner/桌面/xx.txt");
        for (int i=0;i<d.length-2;i++){
             if(d[i]!=null){
            urls.put(new URL(d[i]));
             }else{
                 break;
             }
            }
    
      for(int i=0;i<100;i++)
        new Thread( new CheckURLWorker(Thread.currentThread().getName(),urls)).start();
      
    }
    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;}    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;
        }        public void run() {
            for (URL url = queue.poll(); url != null; url = queue.poll()) {
                try{
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setConnectTimeout(5000);
                   connection.setReadTimeout(13000);
                    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);
                }
            }
        }
    }
}运行很慢啊我扫3万个链接要一个小时(网速是一定的原因,我的网速100k不到)

解决方案 »

  1.   

    最简单的,用时间打印语句看下每一步花费的时间 currentMillis
    找出哪些步骤花费时间多再分析
      

  2.   


                     connection.connect();
                     int code = connection.getResponseCode();
    这个地方耗时间
      

  3.   

    看一下connect耗费多少时间,是否超出正常范围了
    这个方法很底层了,多是网络物理限制,来回几个消息握手之类的
      

  4.   

    我试了一下如果只有一个线程
    connection.connect();
      int code = connection.getResponseCode();耗时1000毫秒内
    线程开多了就耗的时间很长
      

  5.   

    推荐用成熟的线程池来实现多线程,这样子自建的使用效率较低
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.LinkedBlockingQueue;
    import java.util.concurrent.ThreadPoolExecutor;
    import java.util.concurrent.TimeUnit;public class MainClass {  public static void main(String[] args) {
        int nTasks = 5;
        long n = 1000L;
        int tpSize = 10;    ThreadPoolExecutor tpe = new ThreadPoolExecutor(tpSize, tpSize, 50000L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>());    Task[] tasks = new Task[nTasks];
        for (int i = 0; i < nTasks; i++) {
          tasks[i] = new Task(n, "Task " + i);
          tpe.execute(tasks[i]);
        }
        tpe.shutdown();
      }
    }class SingleThreadAccess {  private ThreadPoolExecutor tpe;  public SingleThreadAccess() {
        tpe = new ThreadPoolExecutor(1, 1, 50000L, TimeUnit.SECONDS,
            new LinkedBlockingQueue<Runnable>());
      }  public void invokeLater(Runnable r) {
        tpe.execute(r);
      }  public void invokeAneWait(Runnable r) throws InterruptedException, ExecutionException {
        FutureTask task = new FutureTask(r, null);
        tpe.execute(task);
        task.get();
      }  public void shutdown() {
        tpe.shutdown();
      }
    }class Task implements Runnable {
      long n;  String id;  private long fib(long n) {
        if (n == 0)
          return 0L;
        if (n == 1)
          return 1L;
        return fib(n - 1) + fib(n - 2);
      }  public Task(long n, String id) {
        this.n = n;
        this.id = id;
      }  public void run() {
        Date d = new Date();
        DateFormat df = new SimpleDateFormat("HH:mm:ss:SSS");
        long startTime = System.currentTimeMillis();
        d.setTime(startTime);
        System.out.println("Starting task " + id + " at " + df.format(d));
        fib(n);
        long endTime = System.currentTimeMillis();
        d.setTime(endTime);
        System.out.println("Ending task " + id + " at " + df.format(d) + " after "
            + (endTime - startTime) + " milliseconds");
      }
    }
      

  6.   

    这个确实是网速影响占主要原因,其他原因,如CPU忙,内存不足等系统原因,也会影响
      

  7.   

    楼主把for循环创建线程的循环次数,由100改到10试试,效果可能要好些。
    操作系统虽然是支持多线程的,但是,平常也就300左右各线程在运行。
    楼主一下增加了1/3倍的负载量,并且,大部分都是CPU空闲型的任务,综合效果并不会很强。
    楼主说的慢,可能由以下几个原因造成的:
    1.网络原因。比如,中间某些个节点延迟过高。(暂无解决方案)
    2.系统原因。操作系统负载过大,响应过慢。(可减少系统负载)
    3.程序原因。程序中出现瓶颈,造成效率低下。(更改算法)当然,上述貌似都是废话。
    实在的,就是说,
    1.楼主建了100个线程,一般点的电脑,多跑这么多的线程,会使整个系统性能降低。
    2.每个线程在执行每个任务的周期当中, 大部分时间,都在等待IO的数据响应。使得线程效率不高。
        楼主可以考虑异步IO的通信方式,一个线程,维护多个链接。