博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《go语言程序设计》学习(九)
阅读量:6257 次
发布时间:2019-06-22

本文共 3143 字,大约阅读时间需要 10 分钟。

一,线程安全的类

package safeslicetype safeSlice chan commandDatatype commandData struct {    action  commandAction    index   int    item    interface{}    result  chan<- interface{}    data    chan<- []interface{}    updater UpdateFunc}type commandAction intconst (    insert commandAction = iota    remove    at    update    end    length)type UpdateFunc func(interface{}) interface{}type SafeSlice interface {    Append(interface{})     // Append the given item to the slice    At(int) interface{}     // Return the item at the given index position    Close() []interface{}   // Close the channel and return the slice    Delete(int)             // Delete the item at the given index position    Len() int               // Return the number of items in the slice    Update(int, UpdateFunc) // Update the item at the given index position}func New() SafeSlice {    slice := make(safeSlice)    go slice.run()    return slice}func (slice safeSlice) run() {    list := make([]interface{}, 0)    for command := range slice {        switch command.action {        case insert:            list = append(list, command.item)        case remove: // potentially expensive for long lists            if 0 <= command.index && command.index < len(list) {                list = append(list[:command.index],                    list[command.index+1:]...)            }        case at:            if 0 <= command.index && command.index < len(list) {                command.result <- list[command.index]            } else {                command.result <- nil            }        case length:            command.result <- len(list)        case update:            if 0 <= command.index && command.index < len(list) {                list[command.index] = command.updater(list[command.index])            }        case end:            close(slice)            command.data <- list        }    }}func (slice safeSlice) Append(item interface{}) {    slice <- commandData{action: insert, item: item}}func (slice safeSlice) Delete(index int) {    slice <- commandData{action: remove, index: index}}func (slice safeSlice) At(index int) interface{} {    reply := make(chan interface{})    slice <- commandData{at, index, nil, reply, nil, nil}    return <-reply}func (slice safeSlice) Len() int {    reply := make(chan interface{})    slice <- commandData{action: length, result: reply}    return (<-reply).(int)}// If the updater calls a safeSlice method we will get deadlock!func (slice safeSlice) Update(index int, updater UpdateFunc) {    slice <- commandData{action: update, index: index, updater: updater}}func (slice safeSlice) Close() []interface{} {    reply := make(chan []interface{})    slice <- commandData{action: end, data: reply}    return <-reply}

这是一个线程安全的slice,表面上看,看不到任何锁或者互斥量等任何操作来实现线程安全。

实际上,着应该说,说一个披着slice外衣的actor。。

整个实现说这样:启动一个gorountin,并给它一个channel,当需要操作这个slice点时候,就把希望操作的信息封装进command这个struct内,然后把整个struct打包,从这个channel发送到gorountin,然后这个“slice”有序的从gorountin读取到这个command,就按照command的操作信息,把command操作执行。

如果gorountin没有缓冲区,那么所有多操作都是阻塞的,也就是说,如果1-5这5个线程按顺序的都要操作这个slice,那么,在第一个请求执行完之前,其他线程的请求都时挂起的,直到第一个执行完,按顺序执行第二个。

转载于:https://www.cnblogs.com/mruoli/p/4709382.html

你可能感兴趣的文章
带验证的mvc razor 文本框扩展组件
查看>>
ES6 学习笔记 (2)-- Liunx环境安装Node.js 与 搭建 Node.js 开发环境
查看>>
理解单例模式
查看>>
ios开发日记- 4 键盘隐藏
查看>>
截图工具无法使用解决方法
查看>>
leetcode—Same Tree
查看>>
ABAP文件上传下载 用SMW0
查看>>
对统驭科目和特别总账标志的理解
查看>>
Linux,在不使用U盘的情况下使用wubi.exe程序在Win7上安装ubuntu-14.04.3版系统
查看>>
ListView.setSelection(position)不起作用
查看>>
用纯css改变下拉列表select框的默认样式
查看>>
用例图
查看>>
GamePinTu
查看>>
Tensorflow基础
查看>>
ios之UITabelViewCell的自定义(xib实现2)
查看>>
NOYJ 114(大数加法)
查看>>
回调函数
查看>>
python拆分excel脚本
查看>>
XSS“从1到0”
查看>>
实习小白::(转) Cocos2d-x 3.0 开发(十)使用CocoStudio场景编辑器关联组件
查看>>