golang 并发设计模式(一)--资源生成器模式

golang 并发设计模式(一)--资源生成器模式


在应用系统中,常见的的应用场景就是调用一个生成器:生成订单号,序列号,随机数等。

golang  goroutine为这种需求提供了强大的武器。


1.简单的生成器

[cpp]  view plain  copy
  1. package main  
  2.   
  3. import (  
  4.         "fmt"  
  5.         "math/rand"  
  6. )  
  7.   
  8. func GenerateIntA()chan int {  
  9.         ch := make(chan int ,10)  
  10.         go func(){  
  11.         for {  
  12.                 ch<-rand.Int()  
  13.         }  
  14.         }()  
  15.         return ch  
  16. }  
  17.   
  18. func main(){  
  19.         ch := GenerateIntA()  
  20.         fmt.Println(<-ch)  
  21.         fmt.Println(<-ch)  
  22. }  


2.叠加增强型资源生成器

可以使用多路复用技术进行堆积叠加,增加服务能力
可以使用缓冲chan增加服务能力

[cpp]  view plain  copy
  1. package main  
  2.   
  3. import (  
  4.     "fmt"  
  5.     "math/rand"  
  6. )  
  7.   
  8. func GenerateIntA() chan int {  
  9.     ch := make(chan int, 10)  
  10.     go func() {  
  11.         for {  
  12.             ch <- rand.Int()  
  13.         }  
  14.     }()  
  15.     return ch  
  16. }  
  17.   
  18. func GenerateIntB() chan int {  
  19.     ch := make(chan int, 10)  
  20.     go func() {  
  21.         for {  
  22.             ch <- rand.Int()  
  23.         }  
  24.     }()  
  25.     return ch  
  26. }  
  27.   
  28. func GenerateInt() chan int {  
  29.     ch := make(chan int, 20)  
  30.     go func() {  
  31.         for {  
  32.             select {  
  33.             case ch <- <-GenerateIntA():  
  34.             case ch <- <-GenerateIntB():  
  35.             }  
  36.         }  
  37.     }()  
  38.     return ch  
  39. }  
  40.   
  41. func main() {  
  42.     ch := GenerateInt()  
  43.   
  44.     for i := 0; i < 100; i++ {  
  45.         fmt.Println(<-ch)  
  46.     }  
  47. }  


3.有时我们希望生成器能够自动的退出,这时可以使用golang  channel的

Close channel to broadcast 机制实现:

[cpp]  view plain  copy
  1. package main  
  2.   
  3. import (  
  4.         "fmt"  
  5.         "math/rand"  
  6. )  
  7.   
  8. func GenerateIntA(done chan struct{})chan int {  
  9.         ch := make(chan int )  
  10.         go func(){  
  11.         Lable:  
  12.         for {  
  13.                 select {  
  14.                 case ch<-rand.Int():  
  15.                 case <-done:  
  16.                         break Lable  
  17.         }  
  18.         }  
  19.         close(ch)  
  20. }()  
  21.         return ch  
  22. }  
  23.   
  24. func main(){  
  25.         done :=make(chan struct{})  
  26.         ch := GenerateIntA(done)  
  27.   
  28.         fmt.Println(<-ch)  
  29.         fmt.Println(<-ch)  
  30.         close(done)  
  31.         fmt.Println(<-ch)  
  32.         fmt.Println(<-ch)  
  33.         fmt.Println(<-ch)  
  34.         fmt.Println(<-ch)  
  35. }  


4.可以更牛逼点,既要并发、缓冲,又有通知的生成器:


[cpp]  view plain  copy
  1. package main  
  2.   
  3. import (  
  4.     "fmt"  
  5.     "math/rand"  
  6. )  
  7.   
  8. func GenerateIntA(done chan struct{}) chan int {  
  9.     ch := make(chan int, 5)  
  10.   
  11.     go func() {  
  12.     Lable:  
  13.         for {  
  14.             select {  
  15.             case ch <- rand.Int():  
  16.             case <-done:  
  17.                 break Lable  
  18.             }  
  19.         }  
  20.         close(ch)  
  21.     }()  
  22.     return ch  
  23. }  
  24.   
  25. func GenerateIntB(done chan struct{}) chan int {  
  26.     ch := make(chan int, 10)  
  27.   
  28.     go func() {  
  29.     Lable:  
  30.         for {  
  31.             select {  
  32.             case ch <- rand.Int():  
  33.             case <-done:  
  34.                 break Lable  
  35.             }  
  36.         }  
  37.         close(ch)  
  38.     }()  
  39.     return ch  
  40. }  
  41.   
  42. func GenerateInt(done chan struct{}) chan int {  
  43.     ch := make(chan int)  
  44.     send := make(chan struct{})  
  45.     go func() {  
  46.     Lable:  
  47.         for {  
  48.             select {  
  49.             case ch <- <-GenerateIntA(send):  
  50.             case ch <- <-GenerateIntB(send):  
  51.             case <-done:  
  52.                 send <- struct{}{}  
  53.                 send <- struct{}{}  
  54.                 break Lable  
  55.             }  
  56.         }  
  57.         close(ch)  
  58.     }()  
  59.     return ch  
  60. }  
  61.   
  62. func main() {  
  63.     done := make(chan struct{})  
  64.     ch := GenerateInt(done)  
  65.   
  66.     for i := 0; i < 10; i++ {  
  67.         fmt.Println(<-ch)  
  68.     }  
  69.     done <- struct{}{}  
  70.     for i := 0; i < 10; i++ {  
  71.         v := <-ch  
  72.         if v == 0 {  
  73.             return  
  74.         }  
  75.         fmt.Println(<-ch)  
  76.     }  
  77. }  







版权声明:本文为博主原创文章,未经博主允许不得转载。 http://blog.csdn.net/hittata/article/details/51777426
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值