Android多線程研究(8)——Java中的原子性理解,android多線程

來源:互聯網
上載者:User

Android多線程研究(8)——Java中的原子性理解,android多線程
一、什麼是原子性

原子性是世界上最小單位,具有不可分割性。比如a=0;(a非long和double類型)這個操作是不可分割的,那麼我們說這個操作是原子操作。再比如:a++;這個操作實際上是a=a+1;是可分割的,所以他不是一個原子操作。

二、原子操作的作用非原子操作都會存線上程安全問題,需要我們使用同步技術(sychronized)來讓它變成一個原子操作。一個操作是原子操作,那麼我們就稱它具有原子性。java.util.concurrent.atomic包下提供了一些原子類如下:
三、理解AtomicInteger類下面是AtomicInteger類中幾個常用的方法:
可能很多人和我一樣存在著這樣一個疑問,在AtomicInteger中是如何?原子性的呢?有前輩已經對AtomiInteger的源碼進行了分析《對 AtomicInteger 源碼 的理解》我在這裡僅僅是引用一下,做個記錄。先來看看源碼:
public final int getAndIncrement() {for (;;) {int current = get();int next = current + 1;if (compareAndSet(current, next))return current;}}
看這段代碼和上面對原子性的分析,從int next  = current + 1可以看到,這裡很難保證操作的原子性,重點在於compareAndSet(current, next)方法

該函數 只有兩個參數,可操作的確實三個值 ,即 value ,expect, update. 他使用了 由硬體保證其原子性的指令 CAS (compare and swap)。

compareAndSet  函數保證了 比較,賦值這兩步操作可以通過一個原子操作完成。

然後看整個函數, 所有代碼被放到了一個迴圈裡面, 如果compareAndSet()執行失敗,則說明 在int current = get(); 以後,其他線程對value進行了更新, 於是就迴圈一次,重新擷取當前值,直到compareAndSet()執行成功為止。

綜上,getAndIncrement() 方法並不是原子操作。 只是保證了他和其他函數對 value 值得更新都是有效。他所利用的是基於衝突檢測的開放式並行存取策略。 可以想象,這種樂觀線上程數目非常多的情況下,失敗的機率會指數型增加。

四、理解volatile修飾符

在Java記憶體模型中,有main memory,每個線程也有自己的memory (例如寄存器)。為了效能,一個線程會在自己的memory中保持要訪問的變數的副本。這樣就會出現同一個變數在某個瞬間,在一個線程的memory中的值可能與另外一個線程memory中的值,或者main memory中的值不一致的情況。 
一個變數聲明為volatile,就意味著這個變數是隨時會被其他線程修改的,因此不能將它cache線上程memory中。以下例子展現了volatile的作用: 

package com.codeing.snail.test;public class TestAtomic extends Thread {private volatile boolean pleaseStop;public void run() {while (!pleaseStop) {// do some stuff...}}public void tellMeToStop() {pleaseStop = true;}}
假如pleaseStop沒有被聲明為volatile,線程執行run的時候檢查的是自己的副本,就不能及時得知其他線程已經調用tellMeToStop()修改了pleaseStop的值。 
Volatile一般情況下不能代替sychronized,因為volatile不能保證操作的原子性,即使只是i++,實際上也是由多個原子操作組成:read i; inc; write i,假如多個線程同時執行i++,volatile只能保證他們操作的i是同一塊記憶體,但依然可能出現寫入髒資料的情況。

volatile關鍵字用於聲明簡單類型變數,如int、float、 boolean等資料類型。如果這些單一資料型別聲明為volatile,對它們的操作就會變成原子層級的。但這有一定的限制。例如,下面的例子中的n就不是原子層級的: 

package com.codeing.snail.test;public class TestAtomic extends Thread {public static volatile int n = 0;public void run() {for (int i = 0; i < 10; i++)try {n = n + 1;sleep(3); // 為了使運行結果更隨機,延遲3毫秒} catch (Exception e) {}}public static void main(String[] args) throws Exception {Thread threads[] = new Thread[100];for (int i = 0; i < threads.length; i++)// 建立100個線程threads[i] = new TestAtomic();for (int i = 0; i < threads.length; i++)// 運行剛才建立的100個線程threads[i].start();for (int i = 0; i < threads.length; i++)// 100個線程都執行完後繼續threads[i].join();System.out.println(" n= " + TestAtomic.n);}}
如果對n的操作是原子層級的,最後輸出的結果應該為n=1000,而在執行上面積代碼時,很多時侯輸出的n都小於1000,這說明n=n+1不是原子層級的操作。原因是聲明為volatile的簡單變數如果當前值由該變數以前的值相關,那麼volatile關鍵字不起作用。

五、鎖和Atomic的使用情境

JDK的文檔中說:“設計原子類主要用作各種塊,用於實現非阻塞資料結構和相關基礎結構類。compareAndSet()方法不是鎖定的常規替換方法。僅當對象的重要更新限於單個變數時才應用它”與鎖相比,另外Volatile 變數是一種非常簡單但同時又非常脆弱的同步機制,它在某些情況下將提供優於鎖的效能和伸縮性。如果嚴格遵循 volatile 的使用條件 —— 即變數真正獨立於其他變數和自己以前的值 —— 在某些情況下可以使用 volatile 代替 synchronized 來簡化代碼。然而,使用 volatile 的代碼往往比使用鎖的代碼更加容易出錯。



java 多線程裡面經常提到原子性,那原子性到底是什?教

原子性就是說一個操作不可以被中途cpu暫停然後調度, 即不能被中斷, 要不就執行完, 要不就不執行. 如果一個操作是原子性的, 那麼在多線程環境下, 就不會出現變數被修改等奇怪的問題.
 
怎深刻理解Java多線程?

線程是系統調度中的最小單位,因為其擁有比進程更小的資源消耗,因此,在進行同類事情,需要進行互相的通訊等等事情的時候,都採用線程來進行處理。

對於只做固定的一件事情(比如:計算1+2+3+...+9999999)來說,其效能上不會比採用單線程的整體效率高,原因是,同時都是要做這麼多運算,採用多線程的話,系統在進行線程調度的過程中喙浪費一些資源和時間,從而效能上下降。

那麼,多線程是否就沒有存在的意義了呢?答案當然不是的。多線程還是有存在的價值的,我們在寫輸入資料流輸出資料流,寫網路程式等等的時候,都會出現阻塞的情況,如果說,我們不使用多線程的話,從A中讀資料出來的時候,A因為沒有準備好,而整個程式阻塞了,其他的任何事情都沒法進行。如果採用多線程的話,你就不用擔心這個問題了。還舉個例子:遊戲中,如果A角色和B角色採用同一個線程來處理的話,那麼,很有可能就會出現只會響應A角色的操作,而B角色就始終被佔用了的情況,這樣,玩起來肯定就沒勁了。

因此,線程是有用的,但也不是隨便亂用,亂用的話,可能造成效能的低下,它是有一點的適用範圍的,一般我認為:需要響應多個人的事情,從設計上需要考慮同時做一些事情(這些事情很多情況下可能一點關係都沒有,也有可能有一些關係的)。

使用多線程的時候,如果某些線程之間涉及到資源共用、互相通訊等等問題的時候,一定得注意安全執行緒的問題,根據情況看是不是需要使用synchronized關鍵字。
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.