关于java多线程的小问题 多线程javathread线程 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 要加锁 如果某线程get的时候另一个线程进来for循环 而此时前一个线程做了remove操作 那你的size就有问题了 那你知道为何代码在while()这里出不来吗?为何我改成如下就能出来:while(true){ System.out.println("list:"+list); if(list.isEmpty()){ break; } } list.isEmpty() 这个应该一直假 这个之前加一段代码: System.out.println("list:"+list); 它就能为真,知道为何吗? 个人的一点浅见:应该是 循环中remove导致的例子 :比如 线程1对应的值索引是4 线程2对应的索引是9(list最后一个)当线程2 循环到i=9时,线程1正好remove,导致i>list.size ,跳出循环,线程2对应的值永远也移除不了但是在楼主的这个例子中,runfang方法执行比较简单,通过for循环串行的开启多线程,机器性能好的话和同步执行10次区别不大,第二个线程开启所消耗的时间第一个线程的run方法都可能已经执行完了楼主把run方法 syso的函数放到if(st.equals(list.get(i)))中你会发现凡是卡住的情况,输出都不完整,而写道if外边,无论是否移出都会执行的,输出意义不大 ! 改造了下public class Test extends Thread { private String st; private static List<String> list = new ArrayList<String>(); public Test(int i) { st = "str" + i; } public static void main(String[] args) throws Exception { String[] arr = new String[10]; for (int i = 0; i < arr.length; i++) { arr[i] = "str" + i; list.add(arr[i]); } for (int i = 0; i < arr.length; i++) { Test test = new Test(i); test.start(); } while (true) { if (list.isEmpty()) { break; } sleep(500); } System.out.println("finished"); } public void run() { removeStr(st); System.out.println(st); } public synchronized static void removeStr(String str) { Iterator<String> it = list.iterator(); while (it.hasNext()) { String strTemp = it.next(); if (strTemp.equals(str)) { it.remove(); break; } } } public synchronized static boolean isEmpty() { return list.isEmpty(); }} 是的,这只是个测试用例,实际应用中run中的执行时间是有可能很久的。例如我有成百上千的URL需要测试它是否有效,用单线程的话HttpURLConnection测试的时候即使一个用一秒的话那等待时间也是不可忍受的,所以我想到了多线程,每个URL一个线程,这样执行效率应该高点。 改造了下public class Test extends Thread { private String st; private static List<String> list = new ArrayList<String>(); public Test(int i) { st = "str" + i; } public static void main(String[] args) throws Exception { String[] arr = new String[10]; for (int i = 0; i < arr.length; i++) { arr[i] = "str" + i; list.add(arr[i]); } for (int i = 0; i < arr.length; i++) { Test test = new Test(i); test.start(); } while (true) { if (list.isEmpty()) { break; } sleep(500); } System.out.println("finished"); } public void run() { removeStr(st); System.out.println(st); } public synchronized static void removeStr(String str) { Iterator<String> it = list.iterator(); while (it.hasNext()) { String strTemp = it.next(); if (strTemp.equals(str)) { it.remove(); break; } } } public synchronized static boolean isEmpty() { return list.isEmpty(); }}大神帮忙用多线程改造一下下面的代码:public class Test{public static void main(String[] args) throws Exception { String[] urls = new String[]{..............};//几千个URL地址,一个url测试时间是2秒的话,用单线程那总时间也是无法忍受的。 for(String url : urls){ if(connectURl(url)){ System.out.println("The invalid URL:"+ st[i]); } } }private static boolean connectURl(String urlAddress) { boolean flag = false; int counts = 0; while (counts < 3) { try { URL url = new URL(urlAddress); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setConnectTimeout(10000); int state = con.getResponseCode(); if (state == 200) { flag = true; break; } else { counts++; } } catch (IOException e) { e.printStack(); } } return flag; }} for(int i = 0;i<list.size();i++){if(st.equals(list.get(i))){list.remove(i);}这段代码单线程都有问题,更别说多线程了退一万步讲,还是没问题的话多线程进来就一定是按照线程0、线程1、线程2....顺序执行吗如果不是,那么只要有一个线程执行的时候不是按照进来的顺序执行,那个判断就不成立,就删不掉(前提是不跑异常),那么list就不会为empty 你说的是,我稍微改动了一下private static boolean connectURl(String urlAddress) { boolean flag = false; int counts = 0; while (counts < 3) { try { URL url = new URL(urlAddress); HttpURLConnection con = (HttpURLConnection) url.openConnection(); con.setConnectTimeout(1000); int state = con.getResponseCode(); if (state == 200) { flag = true; break; } else { counts++; } } catch (IOException e) { counts++; } } return flag; }这样就避免了你上面提到的问题。 关于那个删除的问题,可以考虑用Map<String,url>存储,这样就可以好定位map中的元素,以确定删除运行完的URL 多线程例子 http://blog.csdn.net/qq_18994831/article/details/43156019 能说明白点吗?一两句话说不清, 有兴趣加q联系你QQ是多少? 我拷贝了题干中的代码,在Eclipse里面运行了10几次,都是很正常的,最后输出finished。 能说明白点吗?一两句话说不清, 有兴趣加q联系你QQ是多少?~看我个人资料 你的问题在于这行代码:if(st.equals(list.get(i))){st类型是String,list.get(i)返回的是String[]他们两个equals能相等吗?改成这样试试:if(st.equals((list.get(i))[0])){ 正则表达式----------------------- 请教各位,帮忙解决这个return的问题 超级不理解求解 已在该编译单元中定义Timer 想破头皮都没搞顶,请大家帮帮忙,在线等 简单问题 析构方法的工作原理 初学struts就遇到障碍 计算机网络问题 怎么清空一个数组 大家好,请教一个并发问题。重分酬谢!!! java中建立客户端和服务端的思想步骤是如何确立..请大神解答下..
System.out.println("list:"+list);
if(list.isEmpty()){
break;
}
}
应该是 循环中remove导致的
例子 :比如 线程1对应的值索引是4 线程2对应的索引是9(list最后一个)
当线程2 循环到i=9时,线程1正好remove,导致i>list.size ,跳出循环,线程2对应的值永远也移除不了但是在楼主的这个例子中,runfang方法执行比较简单,通过for循环串行的开启多线程,机器性能好的话和同步执行10次区别不大,第二个线程开启所消耗的时间第一个线程的run方法都可能已经执行完了楼主把run方法 syso的函数放到if(st.equals(list.get(i)))中你会发现凡是卡住的情况,输出都不完整,而写道if外边,无论是否移出都会执行的,输出意义不大 !
改造了下public class Test extends Thread {
private String st;
private static List<String> list = new ArrayList<String>(); public Test(int i) {
st = "str" + i;
} public static void main(String[] args) throws Exception {
String[] arr = new String[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = "str" + i;
list.add(arr[i]);
} for (int i = 0; i < arr.length; i++) {
Test test = new Test(i);
test.start();
}
while (true) {
if (list.isEmpty()) {
break;
}
sleep(500);
}
System.out.println("finished");
} public void run() {
removeStr(st);
System.out.println(st);
} public synchronized static void removeStr(String str) {
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String strTemp = it.next();
if (strTemp.equals(str)) {
it.remove();
break;
}
}
} public synchronized static boolean isEmpty() {
return list.isEmpty();
}
}
改造了下public class Test extends Thread {
private String st;
private static List<String> list = new ArrayList<String>(); public Test(int i) {
st = "str" + i;
} public static void main(String[] args) throws Exception {
String[] arr = new String[10];
for (int i = 0; i < arr.length; i++) {
arr[i] = "str" + i;
list.add(arr[i]);
} for (int i = 0; i < arr.length; i++) {
Test test = new Test(i);
test.start();
}
while (true) {
if (list.isEmpty()) {
break;
}
sleep(500);
}
System.out.println("finished");
} public void run() {
removeStr(st);
System.out.println(st);
} public synchronized static void removeStr(String str) {
Iterator<String> it = list.iterator();
while (it.hasNext()) {
String strTemp = it.next();
if (strTemp.equals(str)) {
it.remove();
break;
}
}
} public synchronized static boolean isEmpty() {
return list.isEmpty();
}
}
大神帮忙用多线程改造一下下面的代码:
public class Test{
public static void main(String[] args) throws Exception {
String[] urls = new String[]{..............};//几千个URL地址,一个url测试时间是2秒的话,用单线程那总时间也是无法忍受的。
for(String url : urls){
if(connectURl(url)){
System.out.println("The invalid URL:"+ st[i]);
}
}
}
private static boolean connectURl(String urlAddress) {
boolean flag = false;
int counts = 0;
while (counts < 3) {
try {
URL url = new URL(urlAddress);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(10000);
int state = con.getResponseCode();
if (state == 200) {
flag = true;
break;
} else {
counts++;
}
} catch (IOException e) {
e.printStack();
}
}
return flag;
}
}
if(st.equals(list.get(i))){
list.remove(i);
}
这段代码单线程都有问题,更别说多线程了
退一万步讲,还是没问题的话
多线程进来就一定是按照线程0、线程1、线程2....顺序执行吗
如果不是,那么只要有一个线程执行的时候不是按照进来的顺序执行,那个判断就不成立,就删不掉(前提是不跑异常),那么list就不会为empty
boolean flag = false;
int counts = 0;
while (counts < 3) {
try {
URL url = new URL(urlAddress);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setConnectTimeout(1000);
int state = con.getResponseCode();
if (state == 200) {
flag = true;
break;
} else {
counts++;
}
} catch (IOException e) {
counts++;
}
}
return flag;
}
这样就避免了你上面提到的问题。
你QQ是多少?
你QQ是多少?
~看我个人资料
if(st.equals(list.get(i))){st类型是String,
list.get(i)返回的是String[]
他们两个equals能相等吗?改成这样试试:if(st.equals((list.get(i))[0])){