Java-Synchronized(一)-簡介

關鍵字的作用

摘自JDK 1.8

同步方法支持一種簡單的策略來防止線程干擾h和內存一致性錯誤:如果一個對象對多個線程可見,則對該對象變量的所有讀取或寫入都是通過同步方法完成的。

通俗易懂的

能夠保證在同一時刻最多隻有一個線程在執行該段代碼,以達到確保併發安全的效果。

地位

  1. 作爲關鍵字,被Java語言原生支持
  2. 是最基本的同步手段
  3. 是併發編程的元老級角色,併發編程的必學內容

不使用併發的後果

一段非常簡單的代碼

public class DisappearRequest1 implements Runnable {

    static DisappearRequest1 instance = new DisappearRequest1();

    static int i = 0;

    public static void main(String[] args) throws InterruptedException{
        Thread t1 = new Thread(instance);
        Thread t2 = new Thread(instance);
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.println(i);
    }

    @Override
    public void run() {
        for(int j=0; j<100000; j++) {
            i++;
        }
    }
}

join()是Thread類的一個方法。根據jdk文檔的定義:
public final void join()throws InterruptedException: Waits for this thread to die.
join()方法的作用,是等待這個線程結束;但顯然,這樣的定義並不清晰。
個人認爲"Java 7 Concurrency Cookbook"的定義較爲清晰:
join() method suspends the execution of the calling thread until the object called finishes its execution.
也就是說,t.join()方法阻塞調用此方法的線程(calling thread),直到線程t完成,此線程再繼續;通常用於在main()主線程內,等待其它線程完成再結束main()主線程。

輸出結果自然是遠遠小於200000,基本很少超過160000。原因就是i++這個動作在底層是分成3步來做的

  1. 從內存中讀取i
  2. i++
  3. 寫入內存

如果不控制併發,那麼i的值就會被前一個被爭奪走資源的線程在拿到CPU資源使把i“變小”(相當於後一個線程的對i加的循環沒有作用了)

以上這種情況就是我們說的線程不安全

參考內容

慕課網教程:https://www.imooc.com/video/18481

博客園:https://www.cnblogs.com/techyc/p/3286678.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章