同步和内存可见性

http://www.ibm.com/developerworks/library/j-jtp02244.html?S_TACT=105AGX52&S_CMP=cn-a-j

Most programmers know that thesynchronizedkeyword enforces a mutex (mutual exclusion) that prevents more than one thread at a time from entering a synchronized block protected by a given monitor. But synchronization also has another aspect: It enforces certain memory visibility rules as specified by the JMM. It ensures that caches are flushed when exiting a synchronized block and invalidated when entering one, so that a value written by one thread during a synchronized block protected by a given monitor is visible to any other thread executing a synchronized block protected by that same monitor. It also ensures that the compiler does not move instructions from inside a synchronized block to outside (although it can in some cases move instructions from outside a synchronized block inside). The JMM does not make this guarantee in the absence of synchronization -- which is why synchronization (or its younger sibling, volatile) must be used whenever multiple threads are accessing the same variables.

When a thread exits a synchronized block as part of releasing the associated monitor, the JMM requires that the local processor cache be flushed to main memory. (Actually, the memory model does not talk about caches -- it talks about an abstraction,local memory, which encompasses caches, registers, and other hardware and compiler optimizations.) Similarly, as part of acquiring the monitor when entering a synchronized block, local caches are invalidated so that subsequent reads will go directly to main memory and not the local cache. This process guarantees that when a variable is written by one thread during a synchronized block protected by a given monitor and read by another thread during a synchronized block protected by the same monitor, the write to the variable will be visible by the reading thread. The JMM does not make this guarantee in the absence of synchronization -- which is why synchronization (or its younger sibling,volatile) must be used whenever multiple threads are accessing the same variables.

synchronized关键字的作用:

1. 作为线程间的互斥锁,防止多个线程同时访问由一个监视器保护的同步块

2. 保证内存的可见性。它可以确保,当离开同步块的时候将缓存数据刷新到内存中,当进入同步块的时候使本地缓存失效,从内存中获取最新数据。如果两个同步块被同一个监视器所保护,那么这两个同步块根据运行的时间有一个happen-before的关系,并且在后面执行的同步块中是可以看到前面那个同步块对内存的更新的。

3. 确保编译器不会将同步块中的指令移到同步块外面来(尽管在某些时候可以将同步块外面的指令移入到同步块内)

有一个疑问:

在离开同步块时,会刷新缓存到内存中,此处说的缓存的数据是不是该线程的本地缓存中的所有数据,包括不在同步块中使用的,不是volatile的?

你可能感兴趣的:(thread,cache,IBM,J#,Go)