协程是什么,简单的说

1.我对协程的认识

协程底层也是一个线程池来维护执行,只是将原来的多线程执行方法书写方式,更加同步化;

将异步任务存储在用户态应用数据结构中,然后由语言来控制执行,并保存其各个的执行栈;

用少数的线程执行大量的异步任务,类似golang底层封装了io及网络等操作,碰到block及busy的操作,直接将其挂起执行其他协程任务;

与线程池的不同是,线程池只是复用线程,将任务存储在数据结构中,但是碰到io等操作只能将线程挂起,切换到其他线程,无法做到少数线程处理大量io等操作任务;

2.Kotlin的协程如果对比Golang来说,其实是 "假协程",其实可以看作是一种语法糖将异步回调的写法同步化,底层其实依然是使用的jvm的锁关键字等维护的线程池任务;

举个例子:

执行10w个任务,睡眠3秒后打印数字,使用Golang来实现:

package main

import (
	"strconv"
	"time"
)

func say0(str string) {
	time.Sleep(3 * time.Second)
	println(str)
}

func main() {
	for i := 0; i < 100000; i++ {
		go say0("协程" + strconv.Itoa(i))
	}

	time.Sleep(1000 * time.Second)
}

 结果是,3秒后10w个任务全部打印完成,是我们要的效果;

如果使用Kotlin呢:

object K1 {
    @Throws(InterruptedException::class)
    fun say(s: String?) {
        Thread.sleep(3000)
        println(s)
    }

    @Throws(InterruptedException::class)
    @JvmStatic
    fun main(args: Array) {

        for (i in 0..99999) {
            GlobalScope.launch {
                say("" + i)
            }
        }
        LockSupport.park()
    }
}

三秒后,打印12个任务,并且重复这样的打印效果;12是因为我电脑的核心数为12;

 翻译成Java的写法其实是:

public class T2 {

    public static void say(String s) throws InterruptedException {
        Thread.sleep(3000);
        System.out.println(s);
    }

    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(12);

        for (int i = 0; i < 100000; i++) {
            int finalI = i;
            executorService.execute(() -> {
                try {
                    say(finalI + "");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            });
        }

        LockSupport.park();
    }
}

其实就是使用了一个固定线程数为12个的线程池来执行任务;

 

这个例子我不知道阐述这种观点对不对,不过由此可以,如果遇到大量io的操作行为,Kotlin的这种方式并不能带来什么性能提升抑或是缩减内存的占用;

我觉得Golang的协程优势,充分体现在这种高io阻塞的场景上,以少数线程来执行大量任务;如果是cpu计算场景,则跟线程池比没有任何优势;

如果假想,以上例子是瞬间来了10w的请求,并且每个请求时间都有阻塞的话,则Jvm语言的处理方式可能需要开启10w个线程来执行,从而引发oom及切换线程的高额代价;Golang则可以从容面对,以每个协程4kb的代价,使用相当于核心线程数的线程数量即可完成任务处理;

你可能感兴趣的:(golang)