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"); //輸出的最後一條語句
}