线程输出发生的次数多于想要的(不是数据竞争)

时间:2014-12-10 02:55:39

标签: java multithreading synchronization

String [] urls包含url作为字符串。输入流工作正常。这个问题与线程有关。 String [] url中的元素应该有相同数量的线程,并且每个线程应该处理String [] url中的一个元素,而所有线程都在没有数据竞争的情况下并发运行。除了处理一个String [] urls元素部分的每个线程之外,这似乎都在这里工作。但是,通过示例更容易解释。假设String [] urls包含两个url。在这种情况下,我得到的输入流量是我想要的两倍。应该有“猫狗鱼”的东西得到“猫猫狗狗鱼鱼”。当String [] urls只包含一个元素时,它可以正常工作但不会超过它。

我确实尝试在run()方法中删除for循环(因为它应该只在每个线程发生一次),并将URL url=new URL(urls[i])更改为URL url=new URL(urls[t])但是我得到一个错误说“在封闭范围内定义的局部变量t必须是最终的或有效的最终“并且我不希望t是最终的,因为它根据索引而变化。

public void readData(String[] urls) {
        Thread[] arrThr=new Thread[urls.length];
        for (int t=0; t<arrThr.length; t++) {
            arrThr[t]=new Thread(new Runnable() { 
                public void run() { 
                    for (int i=0; i<urls.length; i++) {
                        String str="";
                        try { 
                            URL url=new URL(urls[i]);
                            URLConnection c=url.openConnection();
                            BufferedReader in = new BufferedReader(new InputStreamReader(c.getInputStream()));
                            String line;
                            while (( line = in.readLine())!=null)
                                if (line.contains("<br>")) 
                                    str += line;    
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        //synchronized method calling here
                    }
                }
            });
        }
        for (int p=0; p<arrThr.length; p++)
            arrThr[p].start();
        for (int q=0; q<arrThr.length; q++)
            try {
                arrThr[q].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

    }

1 个答案:

答案 0 :(得分:0)

您正在让每个线程处理所有网址。移除i方法中的多余run()循环,并将final int i = t;声明为t循环中的第一个语句。最后,将urls参数设为final,你应该很高兴。