1. 程式人生 > >Java併發之同步&非同步(個人屌絲版,有點亂,可以噴)

Java併發之同步&非同步(個人屌絲版,有點亂,可以噴)

0、併發的概念挺多的,對作業系統越是不熟,坑越多,那乾脆對一些常見詞彙先掃盲掃盲吧。

 

1、併發

白話文:一段時間內,多個執行緒、或程序同時執行(其實cpu切片不會同時,但是切換很快,像快槍手)

 

2、同步基本概念

比如有兩個任務,那麼他們是按照先後順序,一個一個執行的

發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回或繼續執行後續操作

3、非同步基本概念

比如也有兩個任務,他們執行的時候,幾乎是同時進行的,不用一個一個方法的執行

一個非同步過程呼叫發出後,呼叫者在沒有得到結果之前,就可以繼續執行後續操作。當這個呼叫完成後,一般通過狀態、通知和回撥來通知呼叫者。對於非同步呼叫,呼叫的返回並不受呼叫者控制

4、方法是同步的,指多執行緒下方法的情況

是指該方法支援多執行緒,比如一個方法加了synchronized

 

5、方法體內是否也為同步,即指的是同步呼叫方法

a、方法呼叫一旦開始後,呼叫者必須等到同步方法返回後,才能繼續後續的行為(此時稱被呼叫的方法為同步方法)

b、就是發出一個功能呼叫時,在沒有得到結果之前,該呼叫就不返回或繼續執行後續操作(此時呼叫者本身是個同步方法)

 

6、方法是非同步的,指多執行緒下方法的情況  

是指該方法不支援多執行緒,多個執行緒可以並行呼叫,將導致無法得到正確的值

7、方法體內是否為非同步,即指的是非同步方法,下面指的呼叫者為非同步方法

a、當一個非同步過程呼叫發出後,呼叫者在沒有得到結果之前,就可以繼續執行後續操作

b、當這個呼叫完成後,一般通過狀態、通知和回撥來通知呼叫者。對於非同步呼叫,呼叫的返回並不受呼叫者控制

 

8、這裡面有個概念,呼叫者本身、以及被呼叫者,其實還是一個方法,只是在不同的場景下,叫不同的名字

比如方法hello(),當hello()自己去執行時,hello()是呼叫者本身(這裡奇葩啊,程式執行的時候,總會被呼叫啊,哪怕是入口方法呢,hello()執行時,肯定也是被呼叫的嘛)

當hello()被其他方法呼叫執行的時候,hello()就是被呼叫者

a、呼叫者本身可以是同步方法、也可以是非同步方法

呼叫者A本身如果是同步方法,那它一定會等方法的返回值回來,再向下執行語句

如果呼叫者A是非同步方法,當在執行一條語句,比如呼叫了hello()方法,此時呼叫者不等hello()方法的返回結果,,就開始執行下面的語句了,看下例子

 

b、被呼叫者B本身可以是同步方法、也可以是非同步方法

如果被呼叫者B是同步方法,那麼方法一定會一條語句語句的執行

如果被呼叫者B是非同步方法,那麼方法的某些語句在執行過程中,是不等返回結果,就會繼續next條語句的執行

 

9、同步非同步通常用來形容一次方法呼叫。

  • 同步方法呼叫一旦開始,呼叫者必須等到方法呼叫返回後,才能繼續後續的行為。
  • 非同步方法呼叫更像一個訊息傳遞,一旦開始,方法呼叫就會立即返回,呼叫者就可以繼續後續的操作。而,非同步方法通常會在另外一個執行緒中,“真實”地執行著。整個過程,不會阻礙呼叫者的工作。

10、而上面說的同步方法,是從多執行緒維度考慮,全稱我覺得應該是多執行緒同步方法,如果一個方法不加synchronized等,那麼就是一個多執行緒非同步方法

 

11、在Java中,如果都是單執行緒下,那麼所有方法都是同步方法,跟你加synchroized等沒啥關係,加不加也一樣

 

12、舉個例子

方法是個同步方法,多執行緒維度下

方法體內進行非同步呼叫,新起一根執行緒

此時我們說printHello()方法是同步的,而裡面具體的執行是非同步的

   public static synchronized void printHello(){ //同步方法
        System.out.print("hello");

        new Thread(new TimerTask() { //非同步呼叫,起一根執行緒去執行耗時任務,呼叫者不會等它執行完
            @Override
            public void run() {

            }
        }).start();

        System.out.print("continue print"); //輸出的最後一條語句
    }