第十八章、groovy并发编程

1、并发

1.1、并发不是并行

  • 并发本质也是一个一个处理,只是快速切换
  • 并行,同时多核CPU同时运行,互不干扰

1.2、groovy并发

线程控制需要处理事情

  • 启动和停止并发任务
  • 协调并发任务
  • 控制获取共享变量

需要引入外部包(GPars)

@Grab('org.codehaus.gpars:gpars:1.2.1')

2、并发集合处理

  • @Grab('org.codehaus.gpars:gpars:1.2.1')
    import static  groovyx.gpars.GParsPool.withPool
    
    def numbers = [1, 2, 3, 4, 5, 6]
    
    def squares = [1, 4, 9,16, 25, 36]
    
    // 括号里面线程数量10
    withPool(10){
        assert squares == numbers.collectParallel {it * it}
    }
    
    

2.1透明并发集合

3、使用map、filter、reduce更加有效

在这里插入图片描述

@Grab('org.codehaus.gpars:gpars:1.2.1')
import static  groovyx.gpars.GParsPool.withPool

withPool {
    assert 55 == [0, 1, 2, 3, 4].parallel
            //每个元素加一,平方之和
            .map{it + 1}
            .map{it **2}
            .reduce{a,b -> a+b}

}


4、数据流task协调

  • import groovyx.gpars.dataflow.Dataflow
    import groovyx.gpars.dataflow.Dataflows
    
    /**
     * @author liangchen* @date 2020/12/18
     */
    @Grab('org.codehaus.gpars:gpars:1.2.1')
    
    // 三个任务,一个任务是要算计一个值, 但是缺少 x, y值, 直到另外两个线程赋值 x,y
    final flow = new Dataflows();
    Dataflow.task {flow.result= flow.x + flow.y}
    Dataflow.task { flow.x = 10 }
    Dataflow.task { flow.y = 5 }
    // 满足即可出结果,忽略下列的值
    Dataflow.task {flow.x=100}
    assert 15 == flow.result
    
    
    
    

4.1、测试死锁

  • import groovyx.gpars.dataflow.Dataflow
    import groovyx.gpars.dataflow.Dataflows
    
    /**
     * @author liangchen* @date 2020/12/18
     */
    @Grab('org.codehaus.gpars:gpars:1.2.1')
    //
    def flow = new Dataflows()
    Dataflow.task { flow.x = flow.y }
    Dataflow.task{flow.y = flow.x}
    
    
    

4.2、Dataflow 连续数据类型

  • import groovyx.gpars.dataflow.Dataflow
    import groovyx.gpars.dataflow.DataflowQueue
    
    /**
     * @author liangchen* @date 2020/12/18
     */
    
    @Grab('org.codehaus.gpars:gpars:1.2.1')
    def chances  = new DataflowQueue()
    def amounts = new DataflowQueue()
    def payouts = new DataflowQueue()
    
    // 定义输入流和输出流,然后进行具体输入
    Dataflow.operator(inputs : [chances, amounts], outputs:[payouts],
            {chance, amount -> payouts << chance * amount})
    Dataflow.task {[0,1,0.2, 0.3].each {chances << it}}
    Dataflow.task {[300, 200, 100].each {amounts << it}}
    
    [30,40,30].each {assert  it == payouts.val}
    

5、显示task协调

  • import groovyx.gpars.actor.Actors
    
    /**
     * @author liangchen* @date 2020/12/18
     */
    // 是不是reactor模型?
    def decrypt = Actors.reactor { code -> code.reverse() }
    
    def audit = Actors.reactor {println it}
    
    def main = Actors.actor{
        decrypt 'terces pot'
        Actors.reactor {
            plainText -> audit plainText
        }
    }
    main.join()
    audit.stop()
    audit.join()
    

5.1、Groovy的力量

def manual = Actors.reactor { message ->
    switch (message) {
        case Number: reply 'number'; break
        case String: reply 'string'; break
    }

}

def auto = Actors.messageHandler {
    when{String message -> reply 'string'}
    when{Number message -> reply 'number'}
}

6、协调task代理

  • /**
     * @author liangchen* @date 2020/12/18
     */
    // 只能代理能够修改原类的方法, 起到保护的作用
    def guard = new Agent<String>()
    guard{updateValue('GPars')}
    
    guard { updateValue(it + ' is groovy!') }
    assert "GPars is groovy!" == guard.val
    
    

7、并发实践

package com.jack.groovy.ch18

import groovyx.gpars.GParsPool
import groovyx.gpars.dataflow.Dataflow
import groovyx.gpars.dataflow.Dataflows

/**
 * @author liangchen* @date 2020/12/18
 */
//Date,      Open,  High,  Low,   Close, Volume,  Adj Close
//
//2009-12-01,202.24,213.95,188.68,210.73,19068700,210.73
class YahooService{
    static getYearEndClosingUnsafe(String ticker, int year) {
        def url = "http://real-chart.finance.yahoo.com/table.csv?" +

                "s=$ticker&a=11&b=1&c=$year&d=11&e=31&f=$year&g=d&ignore=.csv"
        def data = url.toURL().text
        return data.split("\n")[1].split(",")[4].toFloat()
    }

    static getYearEndClosing(String ticker, int year) {
        try {
            getYearEndClosing(ticker, year)
        } catch (all) {
            println "Could not get $ticker, returning -1. $all"
            return -1
        }
    }
}
def tickers = ['AAPL', 'GOOG', 'IBM','ORCL', 'MSFT']
def top = tickers.collect {[ticker:it, price : YahooService.getYearEndClosing(it, 2014)]}
.max{it.price}
assert  top == [ticker:'GOOG', price: 526.4f]

// 使用fork/join
GParsPool.withPool {
    def topFork = tickers.makeConcurrent()
    .collect { [ticker: it, price: YahooService.getYearEndClosing(it, 2014)] }
    .max{ it.price}
    assert  topFork == [ticker:'GOOG', price:526.4f]
}

//使用map/filter/reduce
GParsPool.withPool {
    def topFilter = tickers.parallel
        .map{[ticker: it, price:YahooService.getYearEndClosing(it, 2014)]}
        .max{it.price}
    assert topFilter == [ticker:'GOOG', price:526.4f]
}
// 使用Dataflows

def price = new Dataflows()
tickers.each {ticker ->
    Dataflow.task {price[ticker] = YahooService.getYearEndClosing(ticker, 2014)}
}
topFlow = tickers.max { price[it] }
assert topFlow == 'GOOG' && price[topFlow] == 526.4f

8、总结

  • 看有点云里雾里
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值