gpt4 book ai didi

java - 使用 PropertyChangeListener 锁定策略

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:04:39 25 4
gpt4 key购买 nike

我已经定义了一个具有许多“可观察”属性的类。在内部,该类包含一个执行 I/O 的线程;例如

public class Foo {
private final PropertyChangeSupport support;
private State state;

public Foo() { this.support = new PropertyChangeSupport(this); }

public synchronized State getState() { return state; }

public synchronized void setState(State state) {
if (this.state != state) {
State oldState = this.state;
this.state = state;

// Fire property change *whilst still holding the lock*.
support.firePropertyChange("state", oldState, state);
}
}

public synchronized void start() {
// Start I/O Thread, which will call setState(State) in some circumstances.
new Thread(new Runnable() ...
}
}

我的问题是:我是否应该在持有类锁的同时避免触发属性更改事件? ...也许我应该从单个专用线程(例如“event-multicaster”线程)触发属性更改事件?

当前的设计导致死锁,线程 A 获取了外部类的锁:Bar,然后尝试调用 Foo 上的方法并获取出第二把锁。然而,与此同时,I/O 线程调用 setState(State) 获取对 Foo 的锁定,这会将属性更改事件传播到包含类 Bar 并尝试获取此类的锁...导致死锁。换句话说,属性更改回调设计意味着我无法有效控制获取锁的顺序。

我目前的解决方法是使状态 volatile 并删除 synchronized 关键字,但这似乎是一种困惑;一方面,这意味着无法保证触发属性更改事件的顺序。

最佳答案

如果你需要让其他线程从通知循环回调到你的类中,那么你需要减少同步的范围,使用同步块(synchronized block)而不是同步整个消息(这是从你的帖子中复制的,不知道如果它编译):

public void setState(State state) {
State oldState = null;
synchronized (this) {
if (this.state != state) {
oldState = this.state;
this.state = state;
}
}

if (oldState != null)
support.firePropertyChange("state", oldState, state);
}

保持锁的时间尽可能短。并考虑用同步消息队列替换这些回调(查看 java.util.concurrent)。


编辑,概括答案并添加一些哲学。

先吐槽一下:多线程编程很难。任何告诉你不同的人都是在试图向你推销一些东西。在多线程程序中创建大量相互依赖的连接会导致细微的错误,如果不是彻底的精神错乱的话。

据我所知,简化多线程编程的最佳方法是编写具有明确定义的起点和终点的独立模块——换句话说,actor model .一个单独的 actor 是单线程的;您可以轻松地单独理解和测试它。

纯参与者模型非常适合事件通知:参与者被调用以响应事件,并执行一些操作。它不关心自开始以来是否触发了另一个事件。有时,这还不够:您需要根据另一个线程管理的状态做出决定。没关系:参与者可以查看该状态(以同步方式)并做出决定。

要记住的关键一点(正如 Tom Hawtin 在他的评论中指出的那样)是您现在阅读的状态可能与现在不同一毫秒。您不能永远编写假设您知道对象的确切状态的代码。如果您觉得需要这样做,则需要重新考虑您的设计。

最后的评论:Doug Lea 比你我都聪明。不要试图重新发明 java.util.concurrent 中的类。 .

关于java - 使用 PropertyChangeListener 锁定策略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1470992/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com