Lua coroutine vs Java wait/notify
在上文Lua coroutine 不一樣的多線程編程思路 中想到coroutine的運行機制跟Java中的wait/notify很相似,所以寫了一個簡單程序比較一下。
源代碼
Lua code
co = coroutine.create(function(loops)for i = 1, loops docoroutine.yield()end end)local x = os.clock() local loops = 100 * 1000 * 1000 coroutine.resume(co, loops) for i = 1, loops docoroutine.resume(co) end print(string.format("elapsed time: %.2f\n", os.clock() - x))Java code
public class TestWait {public static void main(String[] args) {WaitClass wc = new WaitClass();wc.start();int loops = 100 * 1000 * 1000;long t1 = System.currentTimeMillis();for (int i = 0; i < loops; i++) {synchronized (wc) {wc.notify();}}long t2 = System.currentTimeMillis();System.out.println("elapsed time: " + (t2 - t1) / 1000l);} }class WaitClass extends Thread {public void run() {while (true) {synchronized (this) {try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}}} }運行結果
Lua elapsed time: 53.36
Java elapsed time: 51
CPU占用
運行環境:4core XEON
Lua 1CPU 100%, 其他CPU0%, total 25% (其中CPU sys 0%)
Java 2個CPU 40%-50%, 其他CPU 0%, total 25% (其中CPU sys 5%-10%)
從結果看,coroutine只利用了一個CPU, 和原理所說完全一致。
Java利用了2個CPU, 各占用了50%的CPU時間運行和50%的時間等待,和設計也一致。另外Java用了5-10%的sys CPU時間用于線程context switch
結論
雖然這兩種程序沒有直接可比性,但仍然可以看出一些有趣的地方:
- Lua雖然在各種性能評比中performance比Java低一個數量級,但在這個場景中也跑平了Java
- Java為了調用notify/wait, 用了同步鎖,因此測試場景對Java不利。
再談coroutine應用場景
今天又看到qiezi的文章并發編程模型:Thread, Coroutine, Callback … 分析得很深入,對這方面感興趣的可以進一步去深入了解。
另外qiezi在Coroutine在并發程序中的應用中提到四種場景,可以理解是對我上篇文章對coroutine應用場景的一種答案。
但是我還是覺得存在疑慮,后面幾種我覺得用多線程/線程池模式也可以很好解決。其實select/epoll異步IO方式跟多線程并不矛盾。多線程并不代表每個線程需要recv阻塞在那里。目前網絡服務器的多線程通常是指業務邏輯處理部分使用多線程。比如Java中用mina來處理連接(相當于epoll),mina在收到數據包之后再分發給負責業務邏輯的thread pool處理。如果是CPU密集型任務,簡單把線程池的線程數設成CPU數即可達到性能最佳。這時如果把線程數設成1,就很類似coroutine模式了。而Java模式所增加的消耗,主要是new runnable class以及線程池調度的開銷。
轉載于:https://blog.51cto.com/timyang/307673
總結
以上是生活随笔為你收集整理的Lua coroutine vs Java wait/notify的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 批处理 远程控制
- 下一篇: 获取JavaScript变量的类型