首页 > 代码库 > Goroutine与Java多线程比较

Goroutine与Java多线程比较

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);
    }
}

执行结果:

$ time java -server -jar run.jar 
CPUs: 2
elapsed time: 351.792s

real	6m8.410s
user	8m50.828s
sys	0m8.616s

Go 语言:

初始化时,貌似会启动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会在这两个线程间运行。效率很高。