4

ブックJava concurrency in practiceには、カスタマイズされたスレッドの例があります (セクション 8.3.4 のリスト 8.7 を参照してください)。以下にコードを貼り付けました。よく分からないことが一つあります。つまり、run()メソッドは volatile 変数debugLifecycleを使用する前にコピーします。また、全体で一貫した値を確保するために、コメントのCopy デバッグ フラグがあります。ここに変数をコピーする必要はありますか? はいの場合、なぜですか?

public class MyAppThread extends Thread {
    public static final String DEFAULT_NAME = "MyAppThread";
    private static volatile boolean debugLifecycle = false;

    public MyAppThread(Runnable r) {
        this(r, DEFAULT_NAME);
    }

    public MyAppThread(Runnable runnable, String name) {
        super(runnable, name + "-" + created.incrementAndGet());
        setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            public void uncaughtException(Thread t,
                                          Throwable e) {
                log.log(Level.SEVERE,
                        "UNCAUGHT in thread " + t.getName(), e);
            }
        });
    }

    public void run() {
        // Question: why copy the volatile variable here?
        // Copy debug flag to ensure consistent value throughout.
        boolean debug = debugLifecycle;
        if (debug) log.log(Level.FINE, "Created " + getName());
        try {
            alive.incrementAndGet();
            super.run();
        } finally {
            alive.decrementAndGet();
            if (debug) log.log(Level.FINE, "Exiting " + getName());
        }
    }
}
4

2 に答える 2

10

キーワードはvolatile通常、変数が複数のスレッドによってアクセスされることを意味します。したがって、その状態のコピーを一度作成します。実行中に別のスレッドがそれを変更しても、コピーは影響を受けません。

それ以外の場合は、最初log.log()の句が実行されても、finally 句は実行されない可能性がありますlog.log()。これは、紛らわしい、または正しくない動作である可能性があります。

いくつかのケースでdebugLifecycle が揮発性ではなかったとしても、コピーを使用する方が良い場合があります。しかしvolatile、この変数はいつでも変更される可能性があるという「危険信号」です。

于 2012-06-08T01:46:26.297 に答える
0

volatile キーワードは、異なるスレッドからアクセスおよび変更できることを意味します。Java では、スレッドがいつ何をするかについての保証はありません (より複雑なことに取りかかるまでは、セマフォとミューテックスについて読むことから始めてください)。したがって、別のスレッドが変数を使用している間に、あるスレッドが変数の値を変更する可能性があります。変数の使用中に値が変更された場合、これは悪影響を与える可能性があります。したがって、それを防ぐために、値を別の変数にコピーし、コピー時の値を保持します (元の揮発性の値は変更される可能性があります)。

于 2012-06-08T01:46:31.337 に答える