zoukankan      html  css  js  c++  java
  • golang goroutine 介绍

    1. Goroutine 是用户态自己实现的线程,调度方式遇到IO/阻塞点方式就会让出cpu时间(其实也看编译器的实现,如果TA在代码里面插入一些yield,也是可以的。 反正现在不是抢占式的。)

    2. 不能设置goroutine ID, 也拿不到(可以调用C API或者自己修改源码暴漏出来,实际上修改起来挺简单的,因为Go的源码写的非常简洁优雅)

    3. goroutine的栈会自动扩容(初始stack很小,2KB,这也是go程序内存占用很小的原因) 4.相对java,多线程调试工具链有待完善,不过我们目前也没有发现需要这种调试的地方,实在需要时通过profile工具和简单的日志就可以( 目前有一些第三方的工具,不过因为并不需要,我们也没有使用过)

    4. 开销非常小,同时运行几百万个一点问题都没有

    5. go func(..) {} ()

    6. golang的最大特点就是这个goroutine非常简单方便,实现功能,都只要按照人类最直接的思维模式写就好(反正可以开大量的goroutine),不像回调的方式那么碎片化(nodejs),也远远不像NIO那么复杂(netty).一句话:可以用最简单的方式写出来非常高性能的并发

    package main

    import (
        "log"
        "sync"
        "sync/atomic"
        "time"
    )

    var total int32 = 0

    func main() {
        // 控制子线程的任务进行,等同于Map/Reduce处理
        wg := &sync.WaitGroup{}
        // 统计运行时间
        ts := time.Now()
        // 启动100万个线程,每个线程执行100次加1的任务,这里使用了锁,防止脏数据
        for i := 0; i < 1000000; i++ {
            // go标记的函数,自动在一个 新的线程中去执行
            go func() {
                // 控制器的执行任务+1
                wg.Add(1)
                // 子线程结束时,控制器的任务执行完成
                defer wg.Done()
                for i := 0; i < 100; i++ {
                    atomic.AddInt32(&total, 1)
                }
            }()
        }

        // 这里主线程休眠一小短时间,防止子线程的任务控制wg.Add(1)还没有触发,主线程就执行完毕
        time.Sleep(1 * time.Millisecond)

        // 等待子线程的任务完成
        wg.Wait()

        // 输出最终运行时间
        log.Printf("启动100万个线程并执行计算任务完成,总计耗时:%v(毫秒) ", time.Now().Sub(ts).Nanoseconds()/1000000)

        // 输出最终结果
        log.Println("最终计算结果为", total)
    }

  • 相关阅读:
    Java核心技术点之动态代理
    一起写一个Android图片加载框架
    Java核心技术点之注解
    Android中的Intent Filter匹配规则介绍
    阿里客户端工程师试题简析——Android应用的闪退(crash)分析
    Android开发之高效加载Bitmap
    Java NIO:浅析I/O模型
    深入探索Android中的Handler
    git常用命令
    SM2
  • 原文地址:https://www.cnblogs.com/smallleiit/p/10286570.html
Copyright © 2011-2022 走看看