java多線程總結四:volatile、synchronized樣本

來源:互聯網
上載者:User

1、synchronized保證同步

先看一個產生偶數的類

package demo.thread;/** *這是一個int產生器的抽象類別 *  */public abstract class IntGenerator {private volatile boolean canceled = false;public abstract int next();public void cancel() {canceled = true;}public boolean isCanceled() {return canceled;}}


 

/* * 產生偶數 */class EvenGenerator extends IntGenerator {private int currentEvenValue = 0;String s = "";@Overridepublic int next() {synchronized (s) {++currentEvenValue;++currentEvenValue;return currentEvenValue;}}////這樣也可以//public synchronized int next() {//++currentEvenValue;//++currentEvenValue;//return currentEvenValue;//}}

注意到在產生偶數是要加同步鎖,否則可能線程1剛好執行了一句++currentEvenValue;操作,就被線程2搶去了cpu,此時線程2執行return currentEvenValue;這時返回的就是一個奇數。加synchronized
就是兩個線程同時只能一個線程執行synchronized 塊的代碼。

測試代碼:

package demo.thread;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;/* * 消費數字 */public class EvenChecker implements Runnable {private IntGenerator generator;private final int id;public EvenChecker(IntGenerator g, int ident) {generator = g;id = ident;}public void run() {while (!generator.isCanceled()) {int val = generator.next();if (val % 2 != 0) {//如果不是偶數System.out.println(val + " not enen!");generator.cancel();}}}public static void test(IntGenerator gp, int count) {ExecutorService exec = Executors.newCachedThreadPool();for (int i = 0; i < count; i++)exec.execute(new EvenChecker(gp, i));exec.shutdown();}public static void test(IntGenerator gp) {test(gp, 10);}public static void main(String[] args) {test(new EvenGenerator());}}

分析:如果產生偶數的類未加synchronized,那麼測試程式將會出現奇數導致退出程式。

 

2、volatile表示原子性,可見度。

      對於多個線程之間共用的變數,每個線程都有自己的一份拷貝,當線程1改變變數值時,其他線程並不馬上知道該變數值改變了,volatile就保證了變數值對各個線程可見,一個線程改變該值,馬上其他線程中該值也改變。原子性表明操作不可中斷,如基本變數賦值。

     程式碼範例:

package demo.thread;public class VolatileDemo implements Runnable {private volatile int i = 0;//volatile設定可見度public synchronized  int getValue() {return i;}private synchronized void enenIncrement() {i++;i++;}@Overridepublic void run() {while (true)enenIncrement();}public static void main(String[] args) {VolatileDemo at = new VolatileDemo();new Thread(at).start();while (true) {int val = at.getValue();if (val % 2 != 0) {//出現奇數,退出程式System.out.println(val+" is not enen!");System.exit(0);}}}}

注意i++操作並不是原子行操作,getValue() 方法也要加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.