簡體   English   中英

為什么有必要復制volatile變量而不是直接使用它?

[英]Why is it necessary to copy the volatile variable instead of using it directly?

實踐中的Java並發性一書中,有一個自定義線程的例子(參見8.3.4節中的清單8.7)。 我粘貼了下面的代碼。 有一點我不太明白。 也就是說, run()方法在使用之前復制volatile變量debugLifecycle 它有一個注釋復制調試標志,以確保始終如一的價值 有沒有必要在這里復制變量? 如果是,為什么?

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());
        }
    }
}

volatile關鍵字通常表示該變量由多個線程訪問。 所以你要復制一次狀態。 如果在您運行時,另一個線程修改它,您的副本將不受影響。

否則可能是第一個log.log()被執行,而不是finally子句的log.log() 這可能是令人困惑或不正確的行為。

即使debugLifecycle在少數情況下是揮發它仍然可能會更好使用副本。 但是volatile是一個“紅旗”,這個變量可能隨時改變。

volatile關鍵字意味着它可以被不同的線程訪問和修改。 在java中,我們無法保證線程什么時候做什么(直到你進入更復雜的東西;從讀取信號量和互斥量開始)。 因此,當另一個線程正在使用它時,一個線程可以更改變量的值。 如果您正在使用變量,並且值發生變化,則可能會產生不良影響。 因此,為了防止這種情況,我們將值復制到另一個變量,並且該值將保留復制時的值(而原始的,易變的值可能會更改)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM