解决方案 »

  1.   

    要加锁  如果某线程get的时候另一个线程进来for循环  而此时前一个线程做了remove操作  那你的size就有问题了 
      

  2.   

    那你知道为何代码在while()这里出不来吗?为何我改成如下就能出来:while(true){
    System.out.println("list:"+list);
    if(list.isEmpty()){
    break;
    }
    }
      

  3.   

    list.isEmpty() 这个应该一直假
      

  4.   

    这个之前加一段代码: System.out.println("list:"+list);  它就能为真,知道为何吗?
      

  5.   

    个人的一点浅见:
    应该是 循环中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外边,无论是否移出都会执行的,输出意义不大 !
      

  6.   


    改造了下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();
    }
    }
      

  7.   

    是的,这只是个测试用例,实际应用中run中的执行时间是有可能很久的。例如我有成百上千的URL需要测试它是否有效,用单线程的话HttpURLConnection测试的时候即使一个用一秒的话那等待时间也是不可忍受的,所以我想到了多线程,每个URL一个线程,这样执行效率应该高点。
      

  8.   


    改造了下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;
    }
    }
      

  9.   

    for(int i = 0;i<list.size();i++){
    if(st.equals(list.get(i))){
    list.remove(i);
    }
    这段代码单线程都有问题,更别说多线程了
    退一万步讲,还是没问题的话
    多线程进来就一定是按照线程0、线程1、线程2....顺序执行吗
    如果不是,那么只要有一个线程执行的时候不是按照进来的顺序执行,那个判断就不成立,就删不掉(前提是不跑异常),那么list就不会为empty
      

  10.   

    你说的是,我稍微改动了一下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;
    }
    这样就避免了你上面提到的问题。
      

  11.   

    关于那个删除的问题,可以考虑用Map<String,url>存储,这样就可以好定位map中的元素,以确定删除运行完的URL
      

  12.   

    多线程例子    http://blog.csdn.net/qq_18994831/article/details/43156019
      

  13.   

    能说明白点吗?一两句话说不清, 有兴趣加q联系
    你QQ是多少?
      

  14.   

    我拷贝了题干中的代码,在Eclipse里面运行了10几次,都是很正常的,最后输出finished。
      

  15.   

    能说明白点吗?一两句话说不清, 有兴趣加q联系
    你QQ是多少?
    ~看我个人资料
      

  16.   

    你的问题在于这行代码:
    if(st.equals(list.get(i))){st类型是String,
    list.get(i)返回的是String[]
    他们两个equals能相等吗?改成这样试试:if(st.equals((list.get(i))[0])){