`

simple data race

阅读更多

Listing 1. Simple data race

public class DataRace {
    static int a = 0;

    public static void main() {
        new MyThread().start();
        a = 1;
    }

    public static class MyThread extends Thread {
        public void run() { 
            System.out.println(a);
        }
    }
} 

 

以上两个线程间就存在简单数据竞争

 

The second thread could be scheduled immediately, printing the initial value of 0 for a . Alternately, the second thread might not run immediately, resulting in the value 1 being printed instead. The output of this program may depend on the JDK you are using, the scheduler of the underlying operating system, or random timing artifacts. Running it multiple times could produce different results.

Visibility hazards

There is actually another data race in Listing 1, besides the obvious race of whether the second thread starts executing before or after the first thread sets a to 1. The second race is a visibility race: the two threads are not using synchronization, which would ensure visibility of data changes across threads. Because there's no synchronization, if the second thread runs after the assignment to a is completed by the first thread, changes made by the first thread may or may not be immediately visible to the second thread. It is possible that the second thread might still see a as having a value of 0 even though the first thread already assigned it a value of 1. This second class of data race, where two threads are accessing the same variable in the absence of proper synchronization, is a complicated subject, but fortunately you can avoid this class of data race by using synchronization whenever you are reading a variable that might have been last written by another thread, or writing a variable that might next be read by another thread. We won't be exploring this type of data race further here, but see the "Synching up with the Java Memory Model" sidebar and the Resources section for more information on this complicated issue.

 

 

 

 

Synching up with the Java Memory Model

The keyword in Java programming enforces mutual exclusion : it ensures that only one thread is executing a given block of code at a given time. But synchronization -- or the lack thereof -- also has other more subtle consequences on multiprocessor systems with weak memory models (that is, platforms that don't necessarily provide cache coherency). Synchronization ensures that changes made by one thread become visible to other threads in a predictable manner. On some architectures, in the absence of synchronization, different threads may see memory operations appear to have been executed in a different order than they actually were executed. This is confusing, but normal -- and critical for achieving good performance on these platforms. If you just follow the rules -- synchronize every time you read a variable that might have been written by another thread or write a variable that may be read next by another thread -- then you won't have any problems. See the Resources section for more information.



 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics