import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * Created by alpha on 14-8-15. */ public class Main { private static final int TIMES = 100 * 1000 * 1000; public static void main(String[] args) throws Exception { ExecutorService service = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); long t1 = System.currentTimeMillis(); for (int i=0;i<TIMES;i++) { service.submit(() -> {}); } service.shutdown(); long t2 = System.currentTimeMillis(); System.out.printf("elapsed time: %.3fs\n", (t2-t1)/1000f); } }
執行結果:java
$ time java -server -jar run.jar CPUs: 2 elapsed time: 351.792s real 6m8.410s user 8m50.828s sys 0m8.616s
Go 語言:shell
初始化時,貌似會啓動4個Goroutine,根據這個特色,判斷當Goroutine < 4時,主線程退出。(有可能會根據不一樣的系統,初始化時,啓動不一樣數量的Goroutine,也可能這四個Goroutine是系統須要使用的。故在測試前,判斷Goroutine啓動了多少個)多線程
package main import ( "runtime" "fmt" "time" ) const ( TIMES = 100 * 1000 * 1000 ) func main() { runtime.GOMAXPROCS(runtime.NumCPU()) fmt.Println("CPUs:", runtime.NumCPU(), "Goroutines:", runtime.NumGoroutine()) t1 := time.Now() for i:=0; i<TIMES; i++ { go func() {}() } for runtime.NumGoroutine() > 4 { //fmt.Println("current goroutines:", runtime.NumGoroutine()) //time.Sleep(time.Second) } t2 := time.Now() fmt.Printf("elapsed time: %.3fs\n", t2.Sub(t1).Seconds()) }
執行結果:併發
$ time ./thread CPUs: 2 elapsed time: 71.974s real 1m12.004s user 1m33.765s sys 0m3.418s
機器配置:Intel(R) Core(TM)2 Duo CPU T5870 @ 2.00GHz,內存8G。測試
因爲Java的多線程機制和Golang的Goroutine機制是不同的,從此次測試能夠看到,當系統發生1億次併發的時候,Java的多線程上下文切換佔據了很多時間,佔用了大量的CPU時間,系統負載較高。Goroutine在執行1億次併發下,在同等線程條件下,處理速度是Java多線程的4倍。因爲Golong在啓動時,會根據runtime.GOMAXPROCS設定同時並行的線程,1億個Goroutine會在這兩個線程間運行。效率很高。線程