<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Concurrency on All about Raspberry Pi</title><link>https://hugozhu.site/tags/concurrency/</link><description>Recent content in Concurrency on All about Raspberry Pi</description><generator>Hugo</generator><language>en</language><lastBuildDate>Sun, 30 Jun 2013 00:00:00 +0000</lastBuildDate><atom:link href="https://hugozhu.site/tags/concurrency/index.xml" rel="self" type="application/rss+xml"/><item><title>Java并发中正确使用volatile</title><link>https://hugozhu.site/post/2013/38-java-volatile-variable/</link><pubDate>Sun, 30 Jun 2013 00:00:00 +0000</pubDate><guid>https://hugozhu.site/post/2013/38-java-volatile-variable/</guid><description>&lt;p&gt;前几天并发编程群里有同学对volatile的用法提出了疑问，刚好我记得Twitter有关实时搜索的这个&lt;a href="http://2011.lucene-eurocon.org/attachments/0002/8787/Busch_twitter_realtime_search_eurocon_11.pdf"&gt;PPT&lt;/a&gt;对这个问题解释的很清晰并有一个实际的应用场景，于是周末把这个问题摘录了一些和并发相关的内容如下：&lt;/p&gt;
&lt;h1 id="并发---定义"&gt;并发 - 定义&lt;/h1&gt;
&lt;h2 id="悲观锁---pressimistic-locking"&gt;悲观锁 - Pressimistic locking&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;一个线性在执行一个操作时持有对一个资源的独占锁。（互斥）&lt;/li&gt;
&lt;li&gt;一般用在冲突比较可能发生的场景下&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="乐观锁---optimistic-locking"&gt;乐观锁 - Optimistic locking&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;尝试采用原子操作，而不需要持有锁；冲突可被检测，如果发生冲突，具有相应的重试逻辑&lt;/li&gt;
&lt;li&gt;通常用在冲突较少发生的场景下&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="非阻塞算法---non-blocking-algorithm"&gt;非阻塞算法 - Non-blocking algorithm&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;算法确保对线程间竞争共享资源时候，不会因为互斥而使任一线程的执行无限延迟；&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="无锁算法---lock-free-algorithm"&gt;无锁算法 - Lock-free algorithm&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;如果系统整个流程的执行是无阻塞的(系统某一部分可能被短暂阻塞)，这种非阻塞算法就是无锁的。&lt;/li&gt;
&lt;li&gt;无锁算法比传统的基于锁的算法对系统的开销更小，且更容易在多核多CPU处理器上扩展；&lt;/li&gt;
&lt;li&gt;在实时系统中可以避免锁带来的延迟；&lt;/li&gt;
&lt;li&gt;CAS (compare and swap)或LL/SC(load linked/store conditional)，以及内存屏障相关的指令经常被用在算法实现中。&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="无等待算法---wait-free-algorithm"&gt;无等待算法 - Wait-free algorithm&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;如果每个线程的执行都是无阻塞的，这种非阻塞算法就是无等待的（比无锁算法更好）&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="java的并发"&gt;Java的并发&lt;/h1&gt;
&lt;ol&gt;
&lt;li&gt;Java的内存模型并不保证一个线程可以一直以程序执行的顺序看到另一个线程对变量的修改，除非两个线程都跨越了同一个内存屏障。（Safe publication）&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="java内存模型"&gt;Java内存模型&lt;/h1&gt;
&lt;h2 id="代码顺序规则"&gt;代码顺序规则&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;一个线程内的每个动作 happens-before 同一个线程内在代码顺序上在其后的所有动作&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="volatile变量规则"&gt;volatile变量规则&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;对一个volatile变量的读，总是能看到（任意线程）对这个volatile变量最后的写入&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="传递性"&gt;传递性&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;如果A happens-before B, B happens-before C，那 A happens-before C&lt;/li&gt;
&lt;/ol&gt;
&lt;h1 id="safe-publication案例"&gt;Safe publication案例&lt;/h1&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-fallback" data-lang="fallback"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;class VolatileExample {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; int x = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; volatile int b = 0;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; private void write() {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; x = 5;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; b = 1;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; private void read() {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; int dummy = b;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; while (x!=5) {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public static void main(String[] args) throws Exception {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; final VolatileExample example = new VolatileExample();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Thread thread1 = new Thread(new Runnable() {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public void run() {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; example.write();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Thread thread2 = new Thread(new Runnable() {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; public void run() {
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; example.read();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; thread1.start();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; thread2.start();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; thread1.join();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; thread2.join();
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;img src="https://www.evernote.com/shard/s26/sh/569ae14f-957d-4ca0-97d7-72f66479d298/b4fb554c924ec7c2356d3ca94d7be61a/deep/0/Screenshot%206/30/13%2010:48%20AM.png"/&gt;
&lt;p&gt;x并不需要定义为&lt;code&gt;volatile&lt;/code&gt;, 程序里可以有需要类似x的变量，我们只需要一个volatile变量b来确保线程a能看到线程1对x的修改：&lt;/p&gt;</description></item></channel></rss>