同步协程

通过睡眠方法

// 通过睡眠方式等待

time.Sleep(time.Second)
<-time.NewTimer(time.Second).C
<-time.After(time.Second)
// 睡眠100毫秒

select {
case <- time.NewTimer(100 * time.Millisecond).C:    // 将在100毫秒可读,返回
}

for {
    time.Sleep(10*time.Second)
}

通过WaitGroup同步

// WaitGroup同步: 无需结果

var wg sync.WaitGroup
wg.Add(2)
wg.Done()
wg.Wait() //阻塞等待

通过有缓冲通道同步

// 缓冲为1 的同步

ch := make(chan int, 1)
go func() {
    println(1)
    ch <- 1
}()
<-ch
println(2)
// 缓冲为10,同步
ch := make(chan int, 10)
for i := 0; i < 10; i++ {
    go func() {
        println(1)
        ch <- i
    }()
}
for i := 0; i < cap(ch); i++ {
    <-ch
}
//有缓冲通道: 返回无序结果

func main() {
    ch := make(chan int, 10)
    //开了10个协程让去干活
    for i := 0; i < 10; i++ {
        go func(i int) {
            ch <- i
        }(i)
    }
    //获取10个协程的结果
    res := []int{}
    for i := 0; i < 10; i++ {
        res = append(res, <-ch)
    }
    //打印10个协程的结果(无序)
    fmt.Println(res)
}

参考

// 从100个url获取结果数据, 后集中返回结果(无序)

type User struct {
    name string
    age  int
}

func getUserInfo(resCh chan User, url string) {
    resCh <- User{
        name: url,
        age:  22,
    }
    println(url)
    time.Sleep(time.Second)
}

func main() {
    //获取100个用户的信息

    var users []User //存放结果数据

    urls := []string{
        "http://www.1.com",
        "http://www.2.com",
        "http://www.3.com",
        "http://www.4.com",
        "http://www.5.com",
    }

    resCh := make(chan User, len(urls))
    defer close(resCh)
    for i := 0; i < len(urls); i++ {
        go getUserInfo(resCh, urls[i])
    }

    for i := 0; i < len(urls); i++ {
        users = append(users, <-resCh)
    }

    //打印结果数据
    fmt.Println(users)
}

channel

//判断chan关闭

func main() {
    ch := make(chan int, 10)
    go func() {
        for i := 0; i < 10; i++ {
            ch <- i
        }
        close(ch)
    }()

    //for i := 0; i < 10; i++ {
    //  println(<-ch)
    //}

    //for {
    //  i, ok := <-ch
    //  if !ok {
    //      break
    //  }
    //  println(i)
    //}

    for v := range ch {
        println(v)
    }
}
//有缓冲通道: 控制任务并发数

func main() {
    ch := make(chan int, 3)
    for i := 0; i < 10; i++ {
        go func() {
            ch <- 1
            println("doing")
            time.Sleep(time.Second / 3)
            <-ch
        }()
    }
    time.Sleep(time.Second)
}
// 管道里有数据即输出: 实现优选返回速度快的

func main() {
    ch := make(chan int, 32)
    go func() {
        time.Sleep(time.Second)
        println("google")
        ch <- 1
    }()
    go func() {
        time.Sleep(time.Second/2)
        println("baidu")
        ch <- 1
    }()
    go func() {
        time.Sleep(time.Second/3)
        println("bing")
        ch <- 1
    }()

    println(<-ch)
}

select

//select: 实现任务超时

func main() {
    ch := make(chan int)
    select {
    case <-ch:
    case <-time.After(time.Second):
        println("timeout")
    }
}
//select分支随机执行: 实现生成随机数
func main() {
    ch := make(chan int)
    go func() {
        for{
            select {
            case ch<-0:
            case ch<-1:
            }
            time.Sleep(time.Second/3)
        }
    }()

    for v := range ch {
        println(v)
    }
}
// select的default分支: 实现goroutine的退出
func main() {
    ch := make(chan int)
    go func() {
        for {
            select {
            case <-ch://接收退出信号
            default: //正常执行
                println("hello")
            }
            time.Sleep(time.Second / 3)
        }
    }()
    time.Sleep(time.Second * 3)
    ch <- 1
}
// close chan发广播: 结束多个goroutine
func main() {
    ch := make(chan int)
    for i := 0; i < 10; i++ {
        go func(i int) {
            for {
                select {
                case <-ch: //接收退出信号
                default: //正常执行
                    println("hello", i)
                }
                time.Sleep(time.Second / 3)
            }
        }(i)
    }

    time.Sleep(time.Second * 3)
    close(ch)
}

[go]go并发的更多相关文章

  1. .Net多线程编程—并发集合

    并发集合 1 为什么使用并发集合? 原因主要有以下几点: System.Collections和System.Collections.Generic名称空间中所提供的经典列表.集合和数组都不是线程安全 ...

  2. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  3. [高并发]Java高并发编程系列开山篇--线程实现

    Java是最早开始有并发的语言之一,再过去传统多任务的模式下,人们发现很难解决一些更为复杂的问题,这个时候我们就有了并发. 引用 多线程比多任务更加有挑战.多线程是在同一个程序内部并行执行,因此会对相 ...

  4. 关于如何提高Web服务端并发效率的异步编程技术

    最近我研究技术的一个重点是java的多线程开发,在我早期学习java的时候,很多书上把java的多线程开发标榜为简单易用,这个简单易用是以C语言作为参照的,不过我也没有使用过C语言开发过多线程,我只知 ...

  5. 如何在高并发环境下设计出无锁的数据库操作(Java版本)

    一个在线2k的游戏,每秒钟并发都吓死人.传统的hibernate直接插库基本上是不可行的.我就一步步推导出一个无锁的数据库操作. 1. 并发中如何无锁. 一个很简单的思路,把并发转化成为单线程.Jav ...

  6. Java多线程基础——对象及变量并发访问

    在开发多线程程序时,如果每个多线程处理的事情都不一样,每个线程都互不相关,这样开发的过程就非常轻松.但是很多时候,多线程程序是需要同时访问同一个对象,或者变量的.这样,一个对象同时被多个线程访问,会出 ...

  7. 多线程的通信和同步(Java并发编程的艺术--笔记)

    1. 线程间的通信机制 线程之间通信机制有两种: 共享内存.消息传递.   2. Java并发 Java的并发采用的是共享内存模型,Java线程之间的通信总是隐式执行,通信的过程对于程序员来说是完全透 ...

  8. 伪共享(false sharing),并发编程无声的性能杀手

    在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...

  9. 编写高质量代码:改善Java程序的151个建议(第8章:多线程和并发___建议126~128)

    建议126:适时选择不同的线程池来实现 Java的线程池实现从根本上来说只有两个:ThreadPoolExecutor类和ScheduledThreadPoolExecutor类,这两个类还是父子关系 ...

  10. 理解Storm并发

    作者:Jack47 PS:如果喜欢我写的文章,欢迎关注我的微信公众账号程序员杰克,两边的文章会同步,也可以添加我的RSS订阅源. 注:本文主要内容翻译自understanding-the-parall ...

随机推荐

  1. mysql使用存储过程,批量生成测试数据

    1.存储过程代码 delimiter $$DROP PROCEDURE IF EXISTS create_service_data$$create procedure create_service_d ...

  2. contextlib:上下文管理器工具

    介绍 contextlib模块包含的工具可以用于处理上下文管理器和with语句 上下文管理器API ''' 上下文管理器(context manager)负责管理一个代码块中的资源,会在进入代码块时创 ...

  3. python面向编程:阶段练习

    1.所有程序都因该使用面向对象来设计吗?为什么? 不是,面向对象编程优点是扩展性高,对程序员来说不需要关心具体的步骤,只需要调用对象功能,缺点是:程序的复杂度变高,整体的可控性比较低! 2.什么是对象 ...

  4. CUDA C编程——NO.1

    CUDA C编程 啥玩意是CUDA? CUDA® is a parallel computing platform and programming model invented by NVIDIA. ...

  5. cubase 的 CC控制器使用

  6. 51Nod 1714 1位数SG异或打表

    SG[i]表示一个数二进制下有i个1的SG值 SG[0]=0 打表: #include<bits/stdc++.h> using namespace std; ]; ]; , x; int ...

  7. 关于TAILQ链表节点删除问题

    这两天偶遇无线驱动中对链表节点删除的问题,刚开始修改代码的时候并没有很在意,把TAILQ链表当成一般的链表来处理,虽然修改以后没有出现段错误,但是后面review代码的时候发现,这样改不对.后面花了点 ...

  8. 数据库允许空值(null),往往是悲剧的开始(1分钟系列)

    数据库字段允许空值,会遇到一些问题,此处包含的一些知识点,和大家聊一聊. 数据准备: create table user ( id int, name varchar(20), index(id) ) ...

  9. HttpRunner完整笔记(从搭建到应用)

    一.安装 (1)       直接python2 –m pip install HttpRunner,安装完成后,可使用hrun –V 来查看安装版本:python2 pip install -U H ...

  10. 使用IDEA创建JavaWeb项目 部署本地tomcat并运行

    一.下载商业版IDEA 官方链接:https://www.jetbrains.com/idea/download/#section=windows 二.新建JavaWeb项目 1.在菜单栏找到File ...