一,线程安全的类
package safeslice type safeSlice chan commandData type commandData struct { action commandAction index int item interface{} result chan<- interface{} data chan<- []interface{} updater UpdateFunc } type commandAction int const ( 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,那么,在第一个请求执行完之前,其他线程的请求都时挂起的,直到第一个执行完,按顺序执行第二个。
时间: 2024-10-12 19:59:36