作者热门文章
- xml - AJAX/Jquery XML 解析
- 具有多重继承的 XML 模式
- .net - 枚举序列化 Json 与 XML
- XML 简单类型、简单内容、复杂类型、复杂内容
我怎样才能将下面的代码翻译成 Go
,你可以在下面看到我的尝试,但是因为我在等待按键输入,所以代码总是返回 20000
,其中java会输出不同的结果。我知道两者都有竞争条件,但我只想知道翻译。
Java
public class Counting {
public static void main(String[] args) throws InterruptedException {
class Counter {
private int count = 0;
public void increment() { ++count; }
public int getCount() { return count; }
}
final Counter counter = new Counter();
class CountingThread extends Thread {
public void run() {
for(int x = 0; x < 10000; ++x)
counter.increment();
}
}
CountingThread t1 = new CountingThread();
CountingThread t2 = new 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())
}
最佳答案
Goroutine 不是线程,因此必须使用同步原语。
您的翻译应该使用 sync.WaitGroup
完成(参见 http://golang.org/pkg/sync/#WaitGroup )。
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())
}
此处演示:http://play.golang.org/p/0SHCvowDjI
它输出“预期”值 20000。
显然这段代码演示了数据竞争:
$ 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)
}
关于go - 线程从 java 到 go,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32369824/
我是一名优秀的程序员,十分优秀!