1// Copyright 2012 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package sync_test
6
7import (
8	"fmt"
9	"os"
10	"sync"
11)
12
13type httpPkg struct{}
14
15func (httpPkg) Get(url string) {}
16
17var http httpPkg
18
19// This example fetches several URLs concurrently,
20// using a WaitGroup to block until all the fetches are complete.
21func ExampleWaitGroup() {
22	var wg sync.WaitGroup
23	var urls = []string{
24		"http://www.golang.org/",
25		"http://www.google.com/",
26		"http://www.example.com/",
27	}
28	for _, url := range urls {
29		// Increment the WaitGroup counter.
30		wg.Add(1)
31		// Launch a goroutine to fetch the URL.
32		go func(url string) {
33			// Decrement the counter when the goroutine completes.
34			defer wg.Done()
35			// Fetch the URL.
36			http.Get(url)
37		}(url)
38	}
39	// Wait for all HTTP fetches to complete.
40	wg.Wait()
41}
42
43func ExampleOnce() {
44	var once sync.Once
45	onceBody := func() {
46		fmt.Println("Only once")
47	}
48	done := make(chan bool)
49	for i := 0; i < 10; i++ {
50		go func() {
51			once.Do(onceBody)
52			done <- true
53		}()
54	}
55	for i := 0; i < 10; i++ {
56		<-done
57	}
58	// Output:
59	// Only once
60}
61
62// This example uses OnceValue to perform an "expensive" computation just once,
63// even when used concurrently.
64func ExampleOnceValue() {
65	once := sync.OnceValue(func() int {
66		sum := 0
67		for i := 0; i < 1000; i++ {
68			sum += i
69		}
70		fmt.Println("Computed once:", sum)
71		return sum
72	})
73	done := make(chan bool)
74	for i := 0; i < 10; i++ {
75		go func() {
76			const want = 499500
77			got := once()
78			if got != want {
79				fmt.Println("want", want, "got", got)
80			}
81			done <- true
82		}()
83	}
84	for i := 0; i < 10; i++ {
85		<-done
86	}
87	// Output:
88	// Computed once: 499500
89}
90
91// This example uses OnceValues to read a file just once.
92func ExampleOnceValues() {
93	once := sync.OnceValues(func() ([]byte, error) {
94		fmt.Println("Reading file once")
95		return os.ReadFile("example_test.go")
96	})
97	done := make(chan bool)
98	for i := 0; i < 10; i++ {
99		go func() {
100			data, err := once()
101			if err != nil {
102				fmt.Println("error:", err)
103			}
104			_ = data // Ignore the data for this example
105			done <- true
106		}()
107	}
108	for i := 0; i < 10; i++ {
109		<-done
110	}
111	// Output:
112	// Reading file once
113}
114