使用Channel的一些业务场景

简介: 使用Channel的一些业务场景

使用Channel的一些业务场景


首先需要明确的就是,发送方才知道什么时候关闭 channel ,这个是比较符合逻辑的。

我们需要知道哪些情况会使 channel 发生 panic


  • 关闭一个 nil 值会引发
  • 关闭一个已经关闭的 channel 会引发
  • 向一个已经关闭的 channel 发送数据会引发


常见应用场景

  • 信号通知
  • 超时控制
  • 生产消费模型
  • 数据传递
  • 控制并发数
  • 互斥锁
  • one million……


信号通知


如果只是单纯的使用通知操作,那么类型就使用 struct{} 。因为空结构体在 go 中是不占用内存空间的


package main
import (
  "fmt"
  "time"
)
func main() {
  isOver := make(chan struct{})
  go func() {
    collectMsg(isOver)
  }()
  <-isOver
  calculateMsg()
}
// 采集
func collectMsg(isOver chan struct{}) {
  time.Sleep(500 * time.Millisecond)
  fmt.Println("完成采集工具")
  isOver <- struct{}{}
}
// 计算
func calculateMsg() {
  fmt.Println("开始进行数据分析")
}

超时控制


<-time.After(1 * time.Second) 是过了指定时间后返回一个 channelselect case 是哪一个 channel 先有反应就先处理,所以可以做到一个超时控制的作用


func main() {
  select {
  case <-doWork():
    fmt.Println("任务结束")
  case <-time.After(1 * time.Second):
    fmt.Println("任务处理超时")
  }
}
func doWork() <-chan struct{} {
  ch := make(chan struct{})
  go func() {
    // 任务处理耗时
    time.Sleep(2 * time.Second)
    close(ch)
  }()
  return ch
}

消费者模型


这个就不多说了,一个生产,一个消费


数据传递

type token struct{}
func main() {
  num := 4
  var chs []chan token
  // 4 个work
  for i := 0; i < num; i++ {
    chs = append(chs, make(chan token))
  }
  for j := 0; j < num; j++ {
    go worker(j, chs[j], chs[(j+1)%num])
  }
  // 先把令牌交给第一个
  chs[0] <- struct{}{}
  select {}
}
func worker(id int, ch chan token, next chan token) {
  for {
    // 对应work 取得令牌
    token := <-ch
    fmt.Println(id + 1)
    time.Sleep(1 * time.Second)
    // 传递给下一个
    next <- token
  }
}


控制并发数


func main() {
  limit := make(chan struct{}, 10)
  jobCount := 100
  for i := 0; i < jobCount; i++ {
    go func(index int) {
      limit <- struct{}{}
      job(index)
      <-limit
    }(i)
  }
  time.Sleep(20 * time.Second)
}
func job(index int) {
  // 耗时任务
  time.Sleep(1 * time.Second)
  fmt.Printf("任务:%d已完成n", index)
}


我们也可以通过 channel 实现一个小小的互斥锁。通过设置一个缓冲区为1的通道,如果成功地往通道发送数据,说明拿到锁,否则锁被别人拿了,等待他人解锁。


type ticket struct{}
type Mutex struct {
  ch chan ticket
}
// 创建一个缓冲区为1的通道作
func newMutex() *Mutex {
  return &Mutex{ch: make(chan ticket, 1)}
}
// 谁能往缓冲区为1的通道放入数据,谁就获取了锁
func (m *Mutex) Lock() {
  m.ch <- struct{}{}
}
// 解锁就把数据取出
func (m *Mutex) unLock() {
  select {
  case <-m.ch:
  default:
    panic("已经解锁了")
  }
}
func main() {
  mutex := newMutex()
  go func() {
    // 如果是1先拿到锁,那么2就要等1秒才能拿到锁
    mutex.Lock()
    fmt.Println("任务1拿到锁了")
    time.Sleep(1 * time.Second)
    mutex.unLock()
  }()
  go func() {
    mutex.Lock()
    // 如果是2拿先到锁,那么1就要等2秒才能拿到锁
    fmt.Println("任务2拿到锁了")
    time.Sleep(2 * time.Second)
    mutex.unLock()
  }()
  time.Sleep(500 * time.Millisecond)
  // 用了一点小手段这里最后才能拿到锁
  mutex.Lock()
  mutex.unLock()
  close(mutex.ch)
}


目录
相关文章
|
缓存 算法
07、Netty学习笔记—(聊天业务优化:参数调优)(二)
07、Netty学习笔记—(聊天业务优化:参数调优)(二)
07、Netty学习笔记—(聊天业务优化:参数调优)(二)
|
2月前
|
消息中间件 存储 监控
MQ线上大规模消息堆积问题处理及使用场景详解
【11月更文挑战第21天】在如今的高并发互联网应用中,消息队列(Message Queue,简称MQ)扮演着至关重要的角色
124 1
|
2月前
|
缓存 NoSQL Java
千万级电商线上无阻塞双buffer缓冲优化ID生成机制深度解析
【11月更文挑战第30天】在千万级电商系统中,ID生成机制是核心基础设施之一。一个高效、可靠的ID生成系统对于保障系统的稳定性和性能至关重要。本文将深入探讨一种在千万级电商线上广泛应用的ID生成机制——无阻塞双buffer缓冲优化方案。本文从概述、功能点、背景、业务点、底层原理等多个维度进行解析,并通过Java语言实现多个示例,指出各自实践的优缺点。希望给需要的同学提供一些参考。
50 7
|
8月前
|
消息中间件 存储 数据库
深度剖析 RocketMQ 5.0,流存储:流场景的诉求是什么?
本文将从使用的角度出发,来更详细的展示一下流存储的场景,看看它和业务消息的场景有哪些区别。 RocketMQ 5.0 面向流存储的场景,提供了哪些特性。再结合两个数据集成的案例,来帮助大家了解流存储的用法。
3535 2
|
消息中间件 Kafka 测试技术
Apache Kafka-消费端_批量消费消息的核心参数及功能实现
Apache Kafka-消费端_批量消费消息的核心参数及功能实现
393 0
|
消息中间件 存储 运维
让数据流动起来,RocketMQ Connect 技术架构解析
本文介绍了 RocketMQ Connect 的概念,然后讲解了 RocketMQ Connect 的实现原理,对服务发现,配置同步,位点同步,负载均衡都有了初步的介绍,接着以 MySqlSourceConnector 为例讲解了如何自己实现一个 Connector,最后对 Connect API 和生态做了一些介绍,提供了一些 RocketMQ Connect 相关的上手教程。
让数据流动起来,RocketMQ Connect 技术架构解析
|
存储 前端开发 Linux
07、Netty学习笔记—(聊天业务优化:参数调优)(一)
07、Netty学习笔记—(聊天业务优化:参数调优)(一)
07、Netty学习笔记—(聊天业务优化:参数调优)(一)
|
缓存 NoSQL 安全
Netty 通道怎么区分对应的用户?
前言 考虑一个功能业务,在web程序中向指定的某个用户进行实时通讯
221 0
Netty 通道怎么区分对应的用户?
|
设计模式 缓存 网络协议
Netty4 Channel 概述(通道篇)
Netty4 Channel 概述(通道篇)
Netty4 Channel 概述(通道篇)
|
Java
深入理解 Netty-Channel架构体系 (三)
深入理解 Netty-Channel架构体系 (三)
159 0

热门文章

最新文章