Synchronization golang与Java synchronized()块的等价物是什么?

Synchronization golang与Java synchronized()块的等价物是什么?,synchronization,go,Synchronization,Go,Java为同步代码的关键部分提供了一种非常方便的习惯用法: synchronized(someObject) { // do something really important all by myself with nobody bothering me } 或 围棋的等价物是什么 (快速搜索显示:-这似乎(也许我错了)对于一般用途来说有点太低了。) (我关心这一点的原因示例:我需要通过通道向多个侦听器发送消息。通道为数据提供了一个良好的通道,而无需同步任何内容,但在添加或删除通道时

Java为同步代码的关键部分提供了一种非常方便的习惯用法:

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++
}