0

私はこのようなクラスを持っています(無関係なコードは削除されています):

public final class Card {

    private boolean important;

    public boolean isImportant() {
        return important;
    }

    public void setImportant(boolean isImportant) {
        this.important = isImportant;
        fireIsImportantChangedEvent(isImportant);
    }

    private EventListenerList listenerList = new EventListenerList();

    private void fireIsImportantChangedEvent(boolean newValue) {
        for (CardListener listener : listenerList.getListeners(CardListener.class)) {
            listener.isImportantChanged(new CardEvent<Boolean>(this, newValue));
        }
    }
}

このクラスをスレッド セーフにしようとしていますが、重要な ( public synchronized boolean isImportant() { ... }and public synchronized void setImportant(boolean isImportant) { ... }) にアクセスするメソッドを同期する必要があるのか​​、それとも重要な volatile ( private volatile boolean important;) を宣言するだけなのかわかりません。setImportant()volatile がイベントを発生させなかった場合 (イベントが発生した場合) は機能することを理解していthis.important = isImportantますが、このイベントを発生させた場合でも volatile は機能しますか?

4

1 に答える 1

1

現時点では、同期を行う必要はありません。リスナーが新しいスレッドを開始しない限り、イベント処理は同じスレッドで発生するようです。その場合は、可視性と同期について考える必要があります。

他のスレッドが重要な値を読み取れるようにする場合は、揮発性にする必要があります。そうしないと、他のスレッドが認識しないようにキャッシュされる可能性があります。同期に関しては、リスナー呼び出しの順序が問題にならない場合は必要ありません。false から true へのマルチスレッド変更が false に戻ることを保証したい場合は、最初にすべて true、次にすべての false イベントを同期する必要があります。現時点では、インスタンス変数から再読み取りするのではなく、newValue を渡しているため、fire メソッドを同期するだけで十分です。

于 2012-11-25T21:52:45.660 に答える