Synchronization golang与Java synchronized()块的等价物是什么?
Java为同步代码的关键部分提供了一种非常方便的习惯用法:Synchronization golang与Java synchronized()块的等价物是什么?,synchronization,go,Synchronization,Go,Java为同步代码的关键部分提供了一种非常方便的习惯用法: synchronized(someObject) { // do something really important all by myself with nobody bothering me } 或 围棋的等价物是什么 (快速搜索显示:-这似乎(也许我错了)对于一般用途来说有点太低了。) (我关心这一点的原因示例:我需要通过通道向多个侦听器发送消息。通道为数据提供了一个良好的通道,而无需同步任何内容,但在添加或删除通道时
synchronized(someObject) {
// do something really important all by myself with nobody bothering me
}
或
围棋的等价物是什么
(快速搜索显示:-这似乎(也许我错了)对于一般用途来说有点太低了。)
(我关心这一点的原因示例:我需要通过通道向多个侦听器发送消息。通道为数据提供了一个良好的通道,而无需同步任何内容,但在添加或删除通道时,我需要修改通道列表,可能随时发生的情况必须能够处理并发性。)是互斥锁,它可以提供与synchronized
java关键字类似的功能(除了java中的锁提供可重入的互斥):
相当于:
var l sync.Mutex
l.Lock()
//
l.Unlock()
使用互斥的另一种解决方案是使用通道来传达侦听器更改
此样式的完整示例如下所示。有趣的代码在FanOuter中
package main
import (
"fmt"
"time"
)
type Message int
type ListenerUpdate struct {
Add bool
Listener chan Message
}
// FanOuter maintains listeners, and forwards messages from msgc
// to each of them. Updates on listc can add or remove a listener.
func FanOuter(msgc chan Message, listc chan ListenerUpdate) {
lstrs := map[chan Message]struct{}{}
for {
select {
case m := <-msgc:
for k := range lstrs {
k <- m
}
case lup := <-listc:
if lup.Add {
lstrs[lup.Listener] = struct{}{}
} else {
delete(lstrs, lup.Listener)
}
}
}
}
func main() {
msgc := make(chan Message)
listc := make(chan ListenerUpdate)
go FanOuter(msgc, listc)
// Slowly add listeners, then slowly remove them.
go func() {
chans := make([]chan Message, 10)
// Adding listeners.
for i := range chans {
chans[i] = make(chan Message)
// A listener prints its id and any messages received.
go func(i int, c chan Message) {
for {
m := <-c
fmt.Printf("%d received %d\n", i, m)
}
}(i, chans[i])
listc <- ListenerUpdate{true, chans[i]}
time.Sleep(300 * time.Millisecond)
}
// Removing listeners.
for i := range chans {
listc <- ListenerUpdate{false, chans[i]}
time.Sleep(300 * time.Millisecond)
}
}()
// Every second send a message to the fanouter.
for i := 0; i < 10; i++ {
fmt.Println("About to send ", i)
msgc <- Message(i)
time.Sleep(1 * time.Second)
}
}
主程序包
进口(
“fmt”
“时间”
)
键入消息int
类型ListenerUpdate结构{
加布尔
陈冯富珍留言
}
//FanOuter维护侦听器,并从msgc转发消息
//给他们每个人。listc上的更新可以添加或删除侦听器。
func Fanuter(msgc chan消息,listc chan ListenerUpdate){
lstrs:=map[chan Message]结构{}{}
为了{
挑选{
案例m:=扩展tarrsalah的答案
您可以将sync.Mutex添加到对象中,允许直接锁定和解锁它们
type MyObject struct{
Number int
sync.Mutex
}
func (m *MyObject)Increment(){
m.Lock()
defer m.Unlock()
m.Number++
}
延迟命令将在函数末尾运行,这样你就知道它在更大的函数中会被锁定和解锁。语义不一样。Java同步块提供重入锁。是的,你是对的@Anonymous,但是Go
没有类似Java的类继承,所以我相信有no需要Go
中的可重入锁在Java中可以工作,但在Go中死锁。继承不起作用。这里的一些讨论:对于我的应用程序,我不需要重入(在我看来,这是最常见的情况),所以这是可行的。这是一个非常好的答案,因为它不只是将java中的锁转换为go,它使用go来解决并发性的初始问题。它还清楚地回答了所述问题。+1这个答案更好,因为它提到了延迟。手动调用unlock()容易出现死锁
package main
import (
"fmt"
"time"
)
type Message int
type ListenerUpdate struct {
Add bool
Listener chan Message
}
// FanOuter maintains listeners, and forwards messages from msgc
// to each of them. Updates on listc can add or remove a listener.
func FanOuter(msgc chan Message, listc chan ListenerUpdate) {
lstrs := map[chan Message]struct{}{}
for {
select {
case m := <-msgc:
for k := range lstrs {
k <- m
}
case lup := <-listc:
if lup.Add {
lstrs[lup.Listener] = struct{}{}
} else {
delete(lstrs, lup.Listener)
}
}
}
}
func main() {
msgc := make(chan Message)
listc := make(chan ListenerUpdate)
go FanOuter(msgc, listc)
// Slowly add listeners, then slowly remove them.
go func() {
chans := make([]chan Message, 10)
// Adding listeners.
for i := range chans {
chans[i] = make(chan Message)
// A listener prints its id and any messages received.
go func(i int, c chan Message) {
for {
m := <-c
fmt.Printf("%d received %d\n", i, m)
}
}(i, chans[i])
listc <- ListenerUpdate{true, chans[i]}
time.Sleep(300 * time.Millisecond)
}
// Removing listeners.
for i := range chans {
listc <- ListenerUpdate{false, chans[i]}
time.Sleep(300 * time.Millisecond)
}
}()
// Every second send a message to the fanouter.
for i := 0; i < 10; i++ {
fmt.Println("About to send ", i)
msgc <- Message(i)
time.Sleep(1 * time.Second)
}
}
type MyObject struct{
Number int
sync.Mutex
}
func (m *MyObject)Increment(){
m.Lock()
defer m.Unlock()
m.Number++
}