5

次のメソッドは、Runnable を実装するオブジェクト A に属します。オブジェクト A からの他のメソッドと run メソッド内のコードによって非同期に呼び出されます (つまり、5 秒間隔で他のスレッドから呼び出されます)。

ファイル作成の例外が発生する可能性はありますか?

メソッドを同期化すると...ロックは常にオブジェクト A で取得されますか? 呼び出し元の 1 人がrun()メソッドにいるという事実は、私を混乱させます :S

ご意見ありがとうございます。

private void saveMap(ConcurrentMap<String, String> map) {
    ObjectOutputStream obj = null;
    try {
        obj = new ObjectOutputStream(new FileOutputStream("map.txt"));
        obj.writeObject(map);

    } catch (IOException ex) {
        Logger.getLogger(MessagesFileManager.class.getName()).log(Level.SEVERE, null, ex);
    } finally {
        try {
            obj.close();
        } catch (IOException ex) {
            Logger.getLogger(MessagesFileManager.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    notifyActionListeners();
}
4

2 に答える 2

6

同期インスタンス メソッドは、オブジェクトをロックとして使用し、異なるスレッドからのすべてのthis同期インスタンス メソッド (他のメソッドも含む) の同時実行を防ぎます。

同期の要件に関する質問に答えるには、同じメソッドにアクセスする複数のスレッドがあり、出力が衝突する可能性があるため、答えは基本的にはいです。

設計コメントとして、私はあなたのsaveMapメソッドを作成します。staticこれはフィールドにアクセスせず (ステートレスです)、ファイルへの出力がインスタンスに依存していないことをより強く示しているため、ファイル出力が衝突する可能性がより明白です。他のインスタンスと。

編集:

私が提案しているもののコードは次のとおりです。

private static synchronized void saveMap(Map<String, String> map) {
    ...
}

参考までに、static synchronizedメソッドはロック オブジェクトとしてシングルトンであるクラス オブジェクト (つまり MyClass.class) を使用します。

于 2012-05-12T23:51:28.407 に答える
0

It's called asynchronously by other method from the object A and by code inside the run method (so, it's called from other thread, with a period of 5 seconds).

Given that saveMap is called from multiple threads, without synchronization you cannot guarantee that two threads won't try to write to the same file concurrently. This will cause an incorrectly-formatted file when it happens.

The simplest solution is to make the method synchronized.

private synchronized void saveMap(ConcurrentMap<String, String> map) { ... }

If the map is large enough, this may cause unresponsiveness in your program. Another option is to write to a temporary file (a new file each time it's called) and then use synchronization while swapping the new file over map.txt by renaming and deleting.

private void saveMap(ConcurrentMap<String, String> map) {
    File file = ... original code to write to a temporary file ...
    if (file != null) {
        synchronized(this) {
            ... move file over map.txt ...
        }
        notifyActionListeners();
    }
}

Keep in mind that swapping two files won't be an atomic operation. Any external program or thread from the same program may catch the short time that map.txt doesn't exist. I was unable to find an atomic file-swap method in Java, but maybe with some searching you will.

于 2012-05-13T00:02:56.907 に答える