我有单例线程类,有时会调用下面的函数并从其线程 run()
方法通知监听器:
public class Serial implements Runnable
{
private ArrayList observers = new ArrayList();
...
public void run()
{
notifyListeners(new CS());
}
public synchronized void notifyListeners(CS value)
{
log.debug("notifying listeners with Control ");
int os = observers.size();
for (int i = 0; i < observers.size(); i++)
{
MListener observer = (MListener) observers.get(i);
observer.dataReceived(value);
}
}
...
public void addListener(MListener lsn)
{
observers.add(lsn);
}
public void removeListener(MListener lsn)
{
observers.remove(lsn);
}
}
我只是想知道notifyListeners
方法上的synchronized
是什么?原因之一 - 在调用 notifyListeners
时不允许向 ArrayList 观察者添加/删除观察者。如果我错了,请纠正我。它还可以提供什么?
更新
我已经使用两个方法 addListener
和 removeListener
更新了我的代码。我认为这是错误的,因为这两种方法都没有同步
并且可能从另一个线程调用?
最佳答案
IMO 通知上的同步没有意义。如果我理解正确的话,notify 方法仅由您的单例线程调用。
但是您的观察者实现内容可能会被不同的线程访问。对内部状态的访问必须同步。
例如如果您想将给定值保存到观察者的成员中,稍后将被例如使用主 GUI 线程,您必须同步对此成员的访问:
// called by your notify thread
void dataReceived( CS value)
{
synchronized (this)
{
myValue = value;
}
}
和:
// called by your GUI main thread:
public CS getValue()
{
synchronized (this)
{
// optional check for not null:
if ( myValue == null) throw new IllegalStateException();
logger.debug( "returning value: " + myValue);
return myValue;
}
}
如果CS是AtomicXY(例如AtomicInteger)类,则不需要同步。但是,如果您想做的不仅仅是分配/返回值(例如一些检查或日志输出),则必须进行同步。
关于java - 了解监听器通知程序上的同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40057516/