我有多个共享ArrayList的同类线程:
static ArrayList<Integer> Terminate_List = new ArrayList<Integer>();
需要更新此ArrayList。我需要删除该列表中的单个项目。问题是当我到达
行时Terminate_List.remove(k);
另一个线程已经删除了列表中的另一个Item,大小已经减少,我得到一个IndexOutOfBoundsException。所以我的计划是使这个方法同步,这样一次只有一个线程可以执行这个方法。该方法由计时器执行。我怎么能一次只让一个线程执行这个方法?
public synchronized void update_list(){
for (int k = 0; k < Terminate_List.size(); k++) {
if (Terminate_List.get(k) == this_ID){
Terminate_List.remove(k); }}}
答案 0 :(得分:1)
请勿使用remove
by index - 使用remove
by reference。这样您根本不必担心索引。
此外,Terminate_List
是静态的,而您的方法则不是。这意味着如果您有多个类的实例,则只有在两个线程区域访问同一实例时才会发生阻塞。要阻止其他线程更新Terminate_List
,您需要更新使用synchronized的方式。
您的代码将变为:
public void update_list(){
// your previous impl was equivalent to synchronized(this)
synchronized (Terminate_List) {
Terminate_List.remove((Integer)this_ID);
}
}
注意 - 我假设this_ID
被定义为int
- 如果它已经是Integer
那么你就不需要演员了(而且你有问题)你的平等检查你的原始代码。)
答案 1 :(得分:0)
这可能是因为您有多个类update_list()
所在的实例以及它们所使用的静态列表。如果是,则需要使用列表作为监视器进行同步:
public void update_list() {
synchronized (terminateList) {
// ...
}
}