協程(Coroutine
)又稱為微執行緒,我們知道執行緒是CPU的執行的最小單位,執行緒執行的最小程式碼單位是方法。
比如在執行的時候,一個執行緒從程式的入口呼叫Main方法,Main呼叫A方法,A方法又呼叫B方法,整個的執行完成的順序是B->A->Main
。這個呼叫的順序是明確的,是通過壓棧和出棧的方式確定的。
而協程不同, Main呼叫B,在呼叫B的過程中可以中斷,Main函式繼續執行一會,Main再中斷,B繼續再執行一會, 繼續執行的程式碼是上次中斷的地方。
用虛擬碼表示兩個方法:
funcA(){ funcB(); print 4; print 5; print 6; } funcB(){ print 1; print 2; print 3; }
如果是用正常的單執行緒執行緒來執行的時候,列印結果是123456
,如果採用協程,列印結果就有可能是142536
.
協程的執行的結果有點和多執行緒類似,但本質與多執行緒不同,執行緒有上下文切換,存在變數的拷貝,而協程只是輕量級的方法中斷,所以切換效率是高於執行緒。
協程所有的變數都是共享記憶體,訪問不需要加鎖,使用時只需簡單的判斷,不存線上程不安全問題。
在java中,還不支援協程的機制,所以用C#來演示下協程的過程。
static void Main(string[] args) { System.Console.WriteLine("執行方法:Main"); IEnumerable<int> intList = Xc.GetList(); foreach (int i in intList) { System.Console.WriteLine("協程1:執行"); Console.WriteLine("協程1:獲得返回的結果是:" + i); } } class Xc { public static IEnumerable<int> GetList() { System.Console.WriteLine("執行方法:GetList"); for (int i = 0; i < 10; i++) { yield return i; System.Console.WriteLine("協程2: 執行"); System.Console.WriteLine("協程2:doSomething"); Thread.Sleep(1000); } } }
執行結果如下:
執行方法:Main 執行方法:GetList 協程1:執行 協程1:獲得返回的結果是:0 協程2: 執行 協程2:doSomething 協程1:執行 協程1:獲得返回的結果是:1 協程2: 執行 協程2:doSomething 協程1:執行 協程1:獲得返回的結果是:2
從上面的結果可以看出,在協程1迴圈執行的時,Main方法會中斷,執行GetList方法,執行GetList到達約定中斷點,Main方法又繼續執行。