我想创建有线程的搜索机制,每个搜索线程目标是在共享列表中查找关键字。
下面是示例代码,所以我需要同步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);
}
}
}
}
}
答案 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;根本不需要任何同步。