マルチスレッド プログラムにいくつかの変更を加えてConcurrentModificationException
、オブジェクトの で sを取得し始めたHashTable
ので、これへのすべてのアクセスをHashTable
メソッドsynchronised
にして、オブジェクトへの同時アクセスを回避しましたが、予想とは異なり、問題は解決しませんでした。使用したデザインの概要は次のとおりです。
最初にJTable
、usb デバイスのデータを表示する があります。これは、必要なデータをオブジェクトを介しJTable
て実装する通信コア オブジェクトObserver
(デバイスにデータを読み書きするObservable
オブジェクト) を要求します。必要なデータは依存します。どの行が表示されるので、ユーザーがテーブルをスクロールすると更新されます。この通信コア オブジェクトは、使用後に最後に読み取った値を保存する他のメソッドsynchronized update
を呼び出すメソッドを介してこの通知を取得します (この通信クラスは、私のクラスに通知します)。および他のオブジェクトを介して値を読み取る場合)。の更新中に、この最後のメソッドで例外が発生しています。コードを簡略化すると、次のようになります。synchronized
HashTable
JTable
Observable
HashTable
以下のメソッドは、通信コア オブジェクトのメソッドです。
public synchronized void update(Observable o, Object arg)
{
// do some other work
// calls the second synchronized method
updateMonitorList();
}
private synchronized void updateMonitorList()
{
// updates a list of monitoring addresses (no problem here)
// m_lastValues is the HashTable that is giving me headaches
Iterator<Parameter> itr = m_lastValues.keySet().iterator();
while (itr.hasNext())
{
// removes the currently not used parameters from the HashTable
Parameter p = itr.next(); // concurrent exception here WHY? :/
boolean contains = false;
for (int i = 0; i < m_monitorList.size(); i++)
{
if (p.equals(m_monitorList.get(i)))
{
contains = true;
break;
}
}
if (!contains)
{
m_lastValues.remove(p);
}
}
// more operations with the HashTable
for (int i = 0; i < m_monitorList.size(); i++)
{
// adds newly added parameters to the hashtable
boolean contains = false;
for (Observer key : m_requestedParameters.keySet())
{
if (key.equals(m_monitorList.get(i)))
{
contains = true;
break;
}
}
if (!contains)
{
m_lastValues.put(m_monitorList.getAt(i), m_monitorList.getAt(i).m_intUserSetting);
}
}
}
// this method is used to know if a value has changed
private synchronized boolean getParameterChanged(Parameter currentParamer)
{
Integer v = m_lastValues.get(currentParamer);
return v == null || v != currentParamer.m_intUserSetting;
}
HashTable
USBデバイスから値を要求する複数のウィンドウがあり、この通信オブジェクトがそれを処理するため、このアプローチが必要です。これを最後の値に追加する前は、同時実行性に問題はありませんでした。これm_lastValues
HashTable
は、上記以外の方法では使用されません。
助言がありますか?前もって感謝します。
[ 編集 ]
実はこれはマルチスレッドの問題ではなく、単に例外の意味が誤解されていたのです。@Tudor が指摘したように、問題はループremove()
内のメソッドでした。while
これが私がそれを解決した方法です:
このコードはupdateMonitorList()
メソッドに入りますno Iterator was needed
(最初の質問はfor
そのようなループでした)、実際にはIterator
違いはありませんでした:
ArrayList<Parameter> remove = new ArrayList<Parameter>();
for (Parameter p : m_lastValues.keySet())
{
boolean contains = false;
for (int i = 0; i < m_monitorList.size(); i++)
{
if (p.equals(m_monitorList.get(i)))
{
contains = true;
break;
}
}
if (!contains)
{
remove.add(p);
}
}
for (int i = 0; i < remove.size(); i++)
{
m_lastValues.remove(remove.get(i));
}