一个线性在执行一个操作时持有对一个资源的独占锁。(互斥)
一般用在冲突比较可能发生的场景下
尝试采用原子操作,而不需要持有锁;冲突可被检测,如果发生冲突,具有相应的重试逻辑
通常用在冲突较少发生的场景下
算法确保对线程间竞争共享资源时候,不会因为互斥而使任一线程的执行无限延迟;
如果系统整个流程的执行是无阻塞的(系统某一部分可能被短暂阻塞),这种非阻塞算法就是无锁的。
无锁算法比传统的基于锁的算法对系统的开销更小,且更容易在多核多cpu处理器上扩展;
在实时系统中可以避免锁带来的延迟;
cas (compare and swap)或ll/sc(load linked/store conditional),以及内存屏障相关的指令经常被用在算法实现中。
如果每个线程的执行都是无阻塞的,这种非阻塞算法就是无等待的(比无锁算法更好)
java的内存模型并不保证一个线程可以一直以程序执行的顺序看到另一个线程对变量的修改,除非两个线程都跨越了同一个内存屏障。(safe publication)
一个线程内的每个动作 happens-before 同一个线程内在代码顺序上在其后的所有动作
对一个volatile变量的读,总是能看到(任意线程)对这个volatile变量最后的写入
如果a happens-before b, b happens-before c,那 a happens-before c
<code>01</code>
<code>class</code> <code>volatileexample {</code>
<code>02</code>
<code> </code><code>int</code> <code>x =</code><code>0</code><code>;</code>
<code>03</code>
<code> </code><code>volatile</code> <code>int</code> <code>b =</code><code>0</code><code>;</code>
<code>04</code>
<code>05</code>
<code> </code><code>private</code> <code>void</code> <code>write() {</code>
<code>06</code>
<code> </code><code>x =</code><code>5</code><code>;</code>
<code>07</code>
<code> </code><code>b =</code><code>1</code><code>;</code>
<code>08</code>
<code> </code><code>}</code>
<code>09</code>
<code>10</code>
<code> </code><code>private</code> <code>void</code> <code>read() {</code>
<code>11</code>
<code> </code><code>int</code> <code>dummy = b;</code>
<code>12</code>
<code> </code><code>while</code> <code>(x !=</code><code>5</code><code>) {</code>
<code>13</code>
<code> </code><code>}</code>
<code>14</code>
<code>15</code>
<code>16</code>
<code> </code><code>public</code> <code>static</code> <code>void</code> <code>main(string[] args)</code><code>throws</code> <code>exception {</code>
<code>17</code>
<code> </code><code>final</code> <code>volatileexample example =</code><code>new</code> <code>volatileexample();</code>
<code>18</code>
<code> </code><code>thread thread1 =</code><code>new</code> <code>thread(</code><code>new</code> <code>runnable() {</code>
<code>19</code>
<code> </code><code>public</code> <code>void</code> <code>run() {</code>
<code>20</code>
<code> </code><code>example.write();</code>
<code>21</code>
<code> </code><code>}</code>
<code>22</code>
<code> </code><code>});</code>
<code>23</code>
<code> </code><code>thread thread2 =</code><code>new</code> <code>thread(</code><code>new</code> <code>runnable() {</code>
<code>24</code>
<code>25</code>
<code> </code><code>example.read();</code>
<code>26</code>
<code>27</code>
<code>28</code>
<code> </code><code>thread1.start();</code>
<code>29</code>
<code> </code><code>thread2.start();</code>
<code>30</code>
<code> </code><code>thread1.join();</code>
<code>31</code>
<code> </code><code>thread2.join();</code>
<code>32</code>
<code>33</code>
<code>}</code>
x并不需要定义为<code>volatile</code>, 程序里可以有需要类似x的变量,我们只需要一个volatile变量b来确保线程a能看到线程1对x的修改:
根据代码顺序规则,线程1的<code>x=5;</code> happens-before <code>b=1;</code>; 线程2的<code>int dummy = b;</code> happens-before <code>while(x!=5);</code>
根据volatile变量规则,线程2的<code>b=1;</code> happens-before <code>int dummy=b;</code>
根据传递性,<code>x=5;</code> happens-before <code>while(x!=5);</code>
在jsr-133之前的旧java内存模型中,虽然不允许volatile变量之间重排序,但旧的java内存模型仍然会允许volatile变量与普通变量之间重排序。jsr-133则增强了volatile的内存语义:严格限制编译器(在编译器)和处理器(在运行期)对volatile变量与普通变量的重排序,确保volatile的写-读和监视器的释放-获取一样,具有相同的内存语义。