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;
}
}
运行了后一直不能结束。
System.out.println("sdf"); 也不能输出
恩,
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 个线程
这样就一直卡着
ArrayBlockingQueue没有实现线程安全
用多线程直接操作很容易出问题
这里初始化为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();一直阻塞,所以程序就不会结束
而且你的线程也有100个,所以按理应该会执行100次threadsSignal.countDown();
这样主线程的threadSignal.await();就不该阻塞的
难道中间有某些线程出异常了?
是不是有些线程可能一直连接不上,要等2分钟发生timeout
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条记录,运行很长时间也没结束
要等2分钟发生timeout 我去掉了也这样
LZ的环境有问题?
为了保证threadsSignal.countDown();一定会被执行,你可以把它放到try finally里
如果不想长时间等待,可以再设置一个线程或者用Timer,设置一定时间后System.exit(-1)退出程序就可以了