同步仅用于搜索的共享列表变量? (JAVA)

时间:2015-02-05 21:11:57

标签: java multithreading

我想创建有线程的搜索机制,每个搜索线程目标是在共享列表中查找关键字。

下面是示例代码,所以我需要同步if条件还是没有必要?

我真的不知道同步括号中哪个部分是原子的

class Search extends Thread {

    private ArrayList<String> searchObject;
    private String what;
    private String name;
    public Search(String name, String what,ArrayList<String> searchObject) {
        this.name=name;
        this.what=what;
        this.searchObject=searchObject;
    }

    public void run() {
        for(int i=0;i<searchObject.size();i++) {
            synchronized (searchObject) {
                if (searchObject.get(i)==what) {
                    System.out.println(name+": "+what+" => "+true);
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您不仅需要围绕if块进行同步,还需要同步整个循环。 (这自然意味着你不会从并行化中看到任何加速。)

否则,您最终可能会:

//Assume the list is initially of length 1.
for(int i=0;i<searchObject.size();i++) {  //On the first iteration, we check the if condition, and that check passes
//Before we acquire the lock, but after testing the condition, some other thread empties the list
        synchronized (searchObject) {
            if (searchObject.get(i)==what) {
//Whoops, we just called get(0) on a list with no contents - IndexOutOfBoundsException!
                System.out.println(name+": "+what+" => "+true);
            }
        }
    }

或者同样令人担心的是:如果您要查找的项目最初位于索引X,则当您在索引X-1之后释放锁定时,有人可能会从列表中删除项目 - 这意味着您的搜索将无法找到它正在寻找的东西,即使它一直在列表中。

当然,只有在您的线程创建后searchObject被修改的情况下,这两者才适用。如果您绝对肯定 List 永远不会在用于构建您的Search课程后进行修改,那么您就不会# 39;根本不需要任何同步。