从java到go的线程

从java到go的线程,go,Go,如何将下面的代码转换为Go,您可以在下面看到我的尝试,但由于我正在等待键输入,代码将始终返回20000,java将在其中输出不同的结果。我知道两者都有种族条件,但我只想知道翻译 爪哇 公共类计数{ 公共静态void main(字符串[]args)引发InterruptedException{ 班级计数器{ 私有整数计数=0; public void increment(){++count;} public int getCount(){return count;} } 最终计数器=新计数器();

如何将下面的代码转换为
Go
,您可以在下面看到我的尝试,但由于我正在等待键输入,代码将始终返回
20000
,java将在其中输出不同的结果。我知道两者都有种族条件,但我只想知道翻译

爪哇

公共类计数{
公共静态void main(字符串[]args)引发InterruptedException{
班级计数器{
私有整数计数=0;
public void increment(){++count;}
public int getCount(){return count;}
}
最终计数器=新计数器();
类CountingThread扩展线程{
公开募捐{
对于(整数x=0;x<10000;++x)
counter.increment();
}
}
CountingThread t1=新的CountingThread();
CountingThread t2=新的CountingThread();
t1.start();t2.start();
t1.join();t2.join();
System.out.println(counter.getCount());
}
}
以下是我的尝试:

import (
  "fmt"
)

type Counting struct {
  count int
}

var counter = Counting{}

func (c *Counting) increment() {
  c.count++
}

func (c *Counting) getCount() int {
  return c.count
}

func CountingThread() {
  for i := 0; i < 10000; i++ {
    counter.increment()
  }
}

func main() {
  go CountingThread()
  go CountingThread()
  var input string
  fmt.Scanln(&input)
  fmt.Println(counter.getCount())
}
导入(
“fmt”
)
类型计数结构{
计数整数
}
变量计数器=计数{}
func(c*计数)增量(){
c、 计数++
}
func(c*计数)getCount()int{
返回c.count
}
func CountingThread(){
对于i:=0;i<10000;i++{
counter.increment()
}
}
func main(){
go CountingThread()
go CountingThread()
变量输入字符串
fmt.扫描和输入
fmt.Println(counter.getCount())
}

goroutine不是线程,因此必须使用同步原语

您的翻译应该使用
sync.WaitGroup
(请参阅)

这可以通过使用原子计数器来解决:

type Counting struct {
        count int32
}

var counter = Counting{}

func (c *Counting) increment() {
        atomic.AddInt32(&c.count, 1)
}

func (c *Counting) getCount() int32 {
        return atomic.LoadInt32(&c.count)
}
见演示在

package main

import (
    "fmt"
    "sync"
)

type Counting struct {
    count int
}

var counter = Counting{}

func (c *Counting) increment() {
    c.count++
}

func (c *Counting) getCount() int {
    return c.count
}

func CountingThread(wg *sync.WaitGroup) {
    for i := 0; i < 10000; i++ {
        counter.increment()
    }
    wg.Done() // mark the goroutine as finished
}

func main() {
    var wg sync.WaitGroup

    wg.Add(2) // we know we'll wait for 2 goroutines

    go CountingThread(&wg)
    go CountingThread(&wg)

    wg.Wait() // wait for the goroutines to both finish

    fmt.Println(counter.getCount())
}
$ go run -race race.go 
==================
WARNING: DATA RACE
Read by goroutine 6:
  main.CountingThread()
      race.go:24 +0x48

Previous write by goroutine 7:
  main.CountingThread()
      race.go:24 +0x5e

Goroutine 6 (running) created at:
  main.main()
      race.go:34 +0x8f

Goroutine 7 (running) created at:
  main.main()
      race.go:35 +0xb1
==================
19042
Found 1 data race(s)
exit status 66
type Counting struct {
        count int32
}

var counter = Counting{}

func (c *Counting) increment() {
        atomic.AddInt32(&c.count, 1)
}

func (c *Counting) getCount() int32 {
        return atomic.LoadInt32(&c.count)
}