Go for Java Programmers

download Go for Java Programmers

of 35

Transcript of Go for Java Programmers

  • 8/13/2019 Go for Java Programmers

    1/35

    Go for Java programmers Hello stack (example) Conceptual differences Syntax Constants Structs Pointers

    Slices

    Making values

    Methods and interfaces Errors Panic and recover Goroutines and channels

    Concurrency (example)

    llustration! e"coli

    #his text is intended to help $ava programmers come up to speed %uickly &ith Go '

    t starts &ith an example highlighting features easily recogni ed y all $ava programmers*then gives a fairly detailed description of Go+s uilding locks* and ends &ith an exampleillustrating constructs that have no immediate counterpart in $ava'

    Hello stack (example)

    #o &het your appetite* &e start &ith a small ut complete and idiomatic examplecorresponding to this Stack',ava program'

    // Package collection implements a generic stack.package collection

    // The zero value for Stack is an empty stack ready to use.type Stack struct { data []interface{}}

    // Push adds to the top of the stack.func !s "Stack# Push! interface{}# { s.data $ append!s.data% #}

    // Pop removes and returns the top element of the stack.// &t's a run(time error to call Pop on an empty stack.func !s "Stack# Pop!# interface{} { i )$ len!s.data# ( * res )$ s.data[i] s.data[i] $ nil // to avoid memory leak s.data $ s.data[)i]

    -

    http://www.nada.kth.se/~snilsson/go_for_java_programmers/#Hellohttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Differenceshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Syntaxhttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Constantshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Structshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Pointershttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Sliceshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Making_valueshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Methods_and_interfaceshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Errorshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Panichttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Goroutineshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Concurrencyhttp://www.flickr.com/photos/e-coli/419976117/http://www.flickr.com/photos/e-coli/419976117/http://golang.org/http://www.nada.kth.se/~snilsson/go_for_java_programmers/src/collection/Stack.javahttp://golang.org/http://www.nada.kth.se/~snilsson/go_for_java_programmers/#Hellohttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Differenceshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Syntaxhttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Constantshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Structshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Pointershttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Sliceshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Making_valueshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Methods_and_interfaceshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Errorshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Panichttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Goroutineshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Concurrencyhttp://www.flickr.com/photos/e-coli/419976117/http://golang.org/http://www.nada.kth.se/~snilsson/go_for_java_programmers/src/collection/Stack.java
  • 8/13/2019 Go for Java Programmers

    2/35

    return res}

    // Size returns the num+er of elements in the stack.func !s "Stack# Size!# int { return len!s.data#

    }stack'go Comments that appear directly efore top"level declarations are documentation

    comments' #hey are &ritten in plain text' .or declarations* your &rite the name follo&ed y the type' / struct corresponds to a class in $ava* ut the mem ers of a struct cannot e

    methods* only varia les' #he type interface{} corresponds to $ava+s ,+-ect ' Ho&ever* it is implemented y

    all types in Go* not only reference types' #he code fragment !s "Stack# declares a method receiver s corresponding to $ava+s

    this ' #he operator )$ oth declares and initiali es a varia le' ts type is deduced from the

    initiali ation expression'

    /nd here is a Hello &orld program demonstrating ho& to use the collection.Stack a stract data type'

    package collection test

    import ! collection . fmt#

    func 0 ample!# { var s collection.Stack s.Push! 1orld # s.Push! hello% # for s.Size!# 2 3 { fmt.Print!s.Pop!## } fmt.Println!# // ,utput) hello% 1orld}example0test'go

    Conceptual differences Go does not have classes &ith constructors' nstead of instance methods* a class

    inheritance hierarchy* and dynamic method lookup* Go provides structs andinterfaces ' nterfaces are also used &here $ava uses generics'

    Go offers pointers to values of all types* not ,ust o ,ects and arrays' .or any type T*there is a corresponding pointer type "T * denoting pointers to values of type T'

    Go allo&s methods on any type1 no oxing is re%uired' #he method receiver * &hichcorresponds to this in $ava* can e a direct value or a pointer'

    2

    http://www.nada.kth.se/~snilsson/go_for_java_programmers/src/collection/stack.gohttp://www.nada.kth.se/~snilsson/go_for_java_programmers/src/collection/example_test.gohttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Structshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Structshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Methods_and_interfaceshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Pointershttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Pointershttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Pointershttp://www.nada.kth.se/~snilsson/go_for_java_programmers/src/collection/stack.gohttp://www.nada.kth.se/~snilsson/go_for_java_programmers/src/collection/example_test.gohttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Structshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Methods_and_interfaceshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Pointers
  • 8/13/2019 Go for Java Programmers

    3/35

    /rrays in Go are values' 3hen an array is used as a function parameter* the functionreceives a copy of the array* not a pointer to it' Ho&ever* in practice functions oftenuse slices for parameters1 slices are references to underlying arrays'

    Strings are provided y the language1 a string ehaves like a slice of ytes* ut isimmuta le'

    Hash ta les are provided y the language' #hey are called maps' Separate threads of execution* goroutines * and communication channels et&een

    them* channels * are provided y the language' Certain types (maps* slices* and channels) are passed y reference* not y value' #hat

    is* passing a map to a function does not copy the map1 if the function changes themap* the change &ill e seen y the caller' n $ava terms* one can think of this as

    eing a reference to the map' Go provides t&o access levels* analogous to $ava+s pu lic and package"private' #op"

    level declarations are pu lic if their names start &ith an upper"case letter* other&isethey are package"private'

    nstead of exceptions* Go uses values of type error to signify events such as end"of"file* and run"time panics for run"time errors such as attempting to index an array outof ounds'

    Go does not support implicit type conversion' 4perations that mix different typesre%uire an explicit conversion'

    Go does not support function overloading' .unctions and methods in the same scopemust have uni%ue names'

    Go uses nil for invalid pointers* &here $ava uses null '

    Syntax

    Declarations

    #he declaration syntax is reversed compared to $ava' 5ou &rite the name follo&ed y thetype' #ype declarations may e read easily from left to right'

    Go Approximate Java equivalentvar v* int int v*4var v5 "int &nteger v54

    var v6 string String v6 $ 4var v7 [*3]int int[] v7 $ ne1 int[*3]4 // v7 is a value in 8o.var v9 []int int[] v94

    6

    http://www.nada.kth.se/~snilsson/go_for_java_programmers/#Sliceshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Goroutineshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Goroutineshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Goroutineshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Goroutineshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Errorshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Errorshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Panichttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Panichttp://www.flickr.com/photos/ruminatrix/3052493260/http://www.nada.kth.se/~snilsson/go_for_java_programmers/#Sliceshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Goroutineshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Goroutineshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Errorshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Panic
  • 8/13/2019 Go for Java Programmers

    4/35

    var v: "struct { a int } ; v:4 // 8iven) class ; { int a4 }var v< map[string]int =ash>ap?String%&nteger2 v

  • 8/13/2019 Go for Java Programmers

    5/35

    "ultiple assignment

    Go permits multiple assignments' #he expressions on the right are evaluated efore assigningto any of the operands on the left'

    i% - $ -% i // S1ap i and -.

    .unctions may have multiple return values* indicated y a list in parentheses' #he returnedvalues can e stored y assignment to a list of varia les'

    func f!# !i int% p- "int# { ... }v*% v5 $ f!#

    # e $lank identifier

    #he lank identifier* represented y the underscore character* provides a &ay to ignore values

    returned y a multi"valued expression!

    v*% $ f!# // &gnore second value returned +y f!#.

    Semicolons and formatting

    nstead of &orrying a out semicolons and formatting* you may use the gofmt program to produce a single standard Go style' 3hile this style may initially seem odd* it is as good asany other style* and familiarity &ill lead to comfort'

    Go code uses very fe& semicolons in practice' #echnically* all Go statements are terminated y a semicolon' Ho&ever* Go implicitly inserts a semicolon at the end of a non" lank lineunless the line is clearly incomplete' / conse%uence of this is that in some cases Go does not

    permit a line reak' .or example* you may not &rite

    func g!#{ // &DEFG&H4 { should +e on previous line.}

    / semicolon &ill e inserted after g!# causing it to e a function declaration rather than afunction definition' Similarly* you may not &rite

    if n $$ 3 {}else { // &DEFG&H4 else { should +e on previous line.}

    / semicolon &ill e inserted after the } preceding the else * causing a syntax error'

    Conditional statements

    Go does not use parentheses around the condition of an if statement* or the expressions of afor statement* or the value of a s1itch statement' 4n the other hand* it does re%uire curly

    races around the ody of an if or for statement'

    9

  • 8/13/2019 Go for Java Programmers

    6/35

    if a ? + { f!# }if !a ? +# { f!# } // Parentheses are unnecessary.if !a ? +# f!# // &DEFG&Hfor i $ 34 i ? *34 iCC {}for !i $ 34 i ? *34 iCC# {} // &DEFG&H

    .urthermore* if and s1itch accept an optional initiali ation statement* &hich is commonlyused to set up a local varia le'

    if err )$ file.;hmod!3::7#4 err I$ nil { log.Print!err# return err}

    !or statements

    Go does not have a 1hile statement nor does it have a do(1hile statement' #he for

    statement may e used &ith a single condition* &hich makes it e%uivalent to a 1hile statement' 4mitting the condition entirely produces an endless loop'

    / for statement may contain a range clause for iterating over strings* arrays* slices* maps* orchannels' nstead of &riting

    for i )$ 34 i ? len!a#4 iCC { ... }

    to loop over the elements of a * &e could also &rite

    for i% v )$ range a { ... }

    #his assigns i to the index and v to the value of the successive elements of an array* slice* orstring' .or strings* i is an index to a yte and v is a :nicode code point of type rune (rune isan alias for int65 )' terations over maps produce key"value pairs* &hile channels produceonly one iteration value'

    %reak and continue

    ;ike $ava* Go permits +reak and continue to specify a la el* ut the la el must refer to afor *s1itch * or select statement'

    S&itc statements

    n a s1itch statement* case la els do not fall through y default* ut you can make them fallthrough y ending a case &ith a fallthrough statement'

    s1itch n {case 3) // empty case +odycase *) f!# // f is not called 1hen n $$ 3.}

  • 8/13/2019 Go for Java Programmers

    7/35

    s1itch n {case 3% *) f!# // f is called if n $$ 3 JJ n $$ *.}

    #he values in a case can e any type that supports the e%uality comparison operator* such asstrings or pointers' / missing s&itch expression is e%uivalent to the expression true '

    s1itch {case n ? 3) f*!#case n $$ 3) f5!#default) f6!#}

    '' and statements

    #he CC and (( may only e used as postfix operators and only in statements* not inexpressions' .or example* you cannot &rite n $ iCC '

    # e defer statement

    / defer statement invokes a function &hose execution is deferred to the moment thesurrounding function returns' #he parameters of the deferred function are computed* andsaved for future use* &hen the defer statement executes'

    f% err )$ os.,pen! filename #defer f.;lose!# // f 1ill +e closed 1hen this function returns.

    Constants

    n Go constants may e untyped ' #his applies to numeric literals* expressions using onlyuntyped constants* and const declarations &here no type is given and the initiali erexpression is untyped' / value derived from an untyped constant ecomes typed &hen it isused &ithin a context that re%uires a typed value' #his permits constants to e used relativelyfreely even though Go has no implicit type conversion'

    var a uintf!a C *# // The untyped numeric constant * +ecomes typed as uint.f!a C *e6# // *e6 is also typed as uint.

    #he language does not impose any limits on the si e of an untyped numeric constant' / limitis only applied &hen a constant is used &here a type is re%uired'

    const huge $ * ?? *33var n int $ huge 22 B@

    f the type is a sent in a varia le declaration and the corresponding expression evaluates to an

    untyped numeric constant* the constant is converted to type rune *int *float:7 * or

    >

  • 8/13/2019 Go for Java Programmers

    8/35

  • 8/13/2019 Go for Java Programmers

    9/35

    f you have an int or a struct or an array* assignment copies the contents of the o ,ect' #oachieve the effect of $ava reference varia les* Go uses pointers' .or any type T* there is acorresponding pointer type "T * denoting pointers to values of type T'

    #o allocate storage for a pointer varia le* use the uilt"in function ne1 * &hich takes a typeand returns a pointer to the allocated storage' #he allocated space &ill e ero"initiali ed forthe type' .or example* ne1!int# allocates storage for a ne& int * initiali es it &ith thevalue 3* and returns its address* &hich has type "int '

    #he $ava code T p $ ne1 T!# * &here T is a class &ith t&o instance varia les a and + of typeint * corresponds to

    type T struct { a% + int }var p "T $ ne1!T#

    or the more idiomatic

    p )$ ne1!T#

    #he declaration var v T * &hich declares a varia le that holds a value of type T* has noe%uivalent in $ava' @alues can also e created and initiali ed using a composite literal'

    v )$ T{*% 5}

    #his is e%uivalent to

    var v Tv.a $ *v.+ $ 5

    .or an operand of type T* the address operator N gives the address of * a value of type "T '

    Slices

    / slice is conceptually a struct &ith three fields! a pointer into an array* a length* and acapacity' Slices support the [] operator to access elements of the underlying array' #he uilt"in

    len function returns the length of the slice' #he uilt"in

    cap function returns the capacity'

    A

    http://www.flickr.com/photos/lwr/374707207/
  • 8/13/2019 Go for Java Programmers

    10/35

    Given an array* or another slice* a ne& slice is created via a[i)-] ' #his creates a ne& slice&hich refers to a * starts at index i * and ends efore index - ' t has length - ( i ' f i isomitted* the slice starts at 3 ' f - is omitted* the slice ends at len!a# ' #he ne& slice refers tothe same array to &hich a refers' #hat is* changes made to the elements using the ne& slicemay e seen using a ' #he capacity of the ne& slice is simply the capacity of a minus i ' #hecapacity of an array is the length of the array'

    var s []intvar a [*3]int

    s $ a[)] // short for s $ a[3)len!a#]

    f you create a value of type [*33]+yte (an array of -BB ytes* perhaps a uffer) and you&ant to pass it to a function &ithout copying it* declare the function parameter to have type[]+yte * and pass a slice of the array' Slices may also e created using the make function asdescri ed elo& '

    Slices com ined &ith the uilt"in function append offer much the same functionality as$ava+s FrrayGist '

    s3 )$ []int{*% 5}s* )$ append!s3% 6# // append a single elements5 )$ append!s*% 7% 9# // append multiple elementss6 )$ append!s5% s3...# // append a slice

    #he slice syntax may also e used &ith a string' t returns a ne& string &hose value is asu string of the original string'

    "aking values

    Map and channel values must e allocated using the uilt"in function make ' .or example*calling

    make!map[string]int#

    returns a ne&ly allocated value of type map[string]int ' /s opposed to ne1 *make returnsthe actual o ,ect* not an address' #his is consistent &ith the fact that maps and channels arereference types'

    .or maps* make takes a capacity hint as an optional second argument' .or channels* there isan optional second argument that sets the uffering capacity of the channel1 the default is B(un uffered)'

    #he make function may also e used to allocate a slice' n this case it allocates memory forthe underlying array and returns a slice referring to it' #here is one re%uired argument* &hichis the num er of elements in the slice' / second optional argument is the capacity of the slice'

    m )$ make![]int% *3% 53# // Same as ne1![53]int#[)*3]

    "et ods and interfaces

    -B

    http://www.nada.kth.se/~snilsson/go_for_java_programmers/#Making_valueshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Making_valueshttp://www.nada.kth.se/~snilsson/go_for_java_programmers/#Making_values
  • 8/13/2019 Go for Java Programmers

    11/35

    "et ods

    / method looks like an ordinary function definition* except that it has a receiver ' #hereceiver is similar to the this reference in a $ava instance method'

    type >yType struct { i int }

    func !p ">yType# 8et!# int { return p.i}

    var pm $ ne1!>yType#var n $ pm.8et!#

    #his declares a method 8et associated &ith >yType ' #he receiver is named p in the ody ofthe function'

    Methods are defined on named types ' f you convert the value to a different type* the ne&value &ill have the methods of the ne& type* not those of the old type'

    5ou may define methods on a uilt"in type y declaring a ne& named type derived from it'#he ne& type is distinct from the uilt"in type'

    type >y&nt int

    func !p >y&nt# 8et!# int { return int!p# // The conversion is reOuired.}

    func f!i int# {}var v >y&nt

    v $ v " v // The operators of the underlying type still apply.f!int!v## // int!v# has no defined methods.f!v# // &DEFG&H

    *nterfaces

    / Go interface is similar to a $ava interface* ut any type that provides the methods named ina Go interface may e treated as an implementation of that interface' o explicit declaration

    is re%uired'Given this interface!

    type >y&nterface interface { 8et!# int Set!i int#}

    Since >yType already has a 8et method* &e can make >yType satisfy the interface y adding

    func !p ">yType# Set!i int# {

    p.i $ i}

    --

  • 8/13/2019 Go for Java Programmers

    12/35

    o& any function &hich takes >y&nterface as a parameter &ill accept a varia le of type">yType '

    func 8etFndSet! >y&nterface# {}

    func f*!# { var p >yType 8etFndSet!Np#}

    n $ava terms* defining Set and 8et for ">yType made ">yType automatically implement>y&nterface ' / type may satisfy multiple interfaces' #his is a form of duck typing'

    3hen see a ird that &alks like a duck and s&ims like a duck and %uacks like a duck* callthat ird a duck'$ames 3hitcom Diley

    Anonymous fields

    /n anonymous field may e used to implement something much like a $ava su class'

    type >ySu+Type struct { >yType - int}

    func !p ">ySu+Type# 8et!# int { p.-CC return p.>yType.8et!#}

    #his effectively implements >ySu+Type as a su type of >yType '

    func f5!# { var p >ySu+Type 8etFndSet!Np#}

    #he Set method is inherited from >yType * ecause methods associated &ith the anonymousfield are promoted to ecome methods of the enclosing type' n this case* ecause >ySu+Type

    has an anonymous field of type >yType * the methods of >yType also ecome methods of>ySu+Type ' #he 8et method &as overridden* and the Set method &as inherited'

    #his is not precisely the same as a su class in $ava' 3hen a method of an anonymous field iscalled* its receiver is the field* not the surrounding struct' n other &ords* methods onanonymous fields are not dynamically dispatched' 3hen you &ant the e%uivalent of $ava+sdynamic method lookup* use an interface'

    func f6!# { var v >y&nterface

    v $ ne1!>yType# v.8et!# // ;all the 8et method for ">yType.

    -2

  • 8/13/2019 Go for Java Programmers

    13/35

    v $ ne1!>ySu+Type# v.8et!# // ;all the 8et method for ">ySu+Type.}

    #ype assertions

    / varia le that has an interface type may e converted to have a different interface type usinga type assertion' #his is implemented dynamically at run time' :nlike $ava* there does notneed to e any declared relationship et&een the t&o interfaces'

    type Printer interface { Print!#}

    func f7! >y&nterface# { .!Printer#.Print!# // type assertion to Printer}

    #he conversion to Printer is entirely dynamic' t &ill &ork as long as the dynamic type of x(the actual type of the value stored in ) defines a Print method'

    Generics

    Go doesn+t have generic types* ut y com ining anonymous fields and type assertions it+s possi le to achieve something akin to $ava+s parameteri ed types'

    type StringStack struct { Stack

    }func !s "StringStack# Push!n string# { s.Stack.Push!n# }func !s "StringStack# Pop!# string { return s.Stack.Pop!#.!string# }

    StringStack speciali es the generic Stack from the Hello stack example so that it operateson string elements only ,ust like Stack?String2 in $ava' otice that the Size method isinherited from Stack '

    +rrors

    Go+s multivalued return makes it easy to return a detailed error message alongside the normalreturn value'

  • 8/13/2019 Go for Java Programmers

    14/35

    f% err )$ os.,pen! filename.e t #if err I$ nil { log.Aatal!err#}// do something 1ith the open "Aile f

    #he error interface re%uires only an 0rror method* ut specific error implementationsoften have additional methods* allo&ing callers to inspect the details of the error'

    anic and recover

    / panic is a run"time error that un&inds the stack of the goroutine* running any deferredfunctions along the &ay* and then stops the program' Panics are similar to $ava exceptions*

    ut are only intended for run"time errors* such as follo&ing a nil pointer or attempting toindex an array out of ounds' #o signify events such as end"of"file* Go programs use the

    uilt"in error type as descri ed a ove '

    #he uilt"in function recover can e used to regain control of a panicking goroutine andresume normal execution' / call to recover stops the un&inding and returns the argument

    passed to panic '

  • 8/13/2019 Go for Java Programmers

    15/35

    Goroutines are light&eight* costing little more than the allocation of stack space' #he stacksstart small and gro& y allocating and freeing heap storage as re%uired' nternally goroutinesact like coroutines that are multiplexed among multiple operating system threads' 5ou do nothave to &orry a out these details'

    go list.Sort!# // un list.Sort in parallel4 don't 1ait for it.

    Go has function literals* &hich can act as closures and are po&erful &hen coupled &ith thego statement'

    // Pu+lish prints te t to stdout after the given time has e pired.func Pu+lish!te t string% delay time.Huration# { go func!# { time.Sleep!delay# fmt.Println!te t# }!# // Dote the parentheses. Qe must call the function.}

    #he varia les te t and delay are shared et&een the surrounding function and the functionliteral1 they survive as long as they are accessi le'

    C annels

    / channel provides a mechanism for t&o goroutines to synchroni e execution andcommunicate y passing a value of a specified element type' #he ?( operator specifies thechannel direction* send or receive' f no direction is given* the channel is i"directional'

    chan T // can +e used to send and receive values of type Tchan?( float:7 // can only +e used to send float:7s?(chan int // can only +e used to receive ints

    Channels are a reference type and are allocated &ith make'

    ic )$ make!chan int# // un+uffered channel of ints1c )$ make!chan "Qork% *3# // +uffered channel of pointers to Qork

    #o send a value on a channel* use ?( as a inary operator' #o receive a value on a channel*use it as a unary operator'

    ic ?( 6 // Send 6 on the channel.1ork )$ ?(1c // eceive a pointer to Qork from the channel.

    f the channel is un uffered* the sender locks until the receiver has received the value' f thechannel has a uffer* the sender locks only until the value has een copied to the uffer1 ifthe uffer is full* this means &aiting until some receiver has retrieved a value' Deceivers

    lock until there is data to receive'

    #he close function records that no more values &ill e sent on a channel' /fter callingclose * and after any previously sent values have een received* receive operations &ill returna ero value &ithout locking' / multi"valued receive operation additionally returns an

    indication of &hether the channel is closed'

    -9

  • 8/13/2019 Go for Java Programmers

    16/35

    ch )$ make!chan string#go func!# { ch ?( =elloI close!ch#}!#fmt.Println!?(ch# // Print =elloI .

    fmt.Println!?(ch# // Print the zero value 1ithout +locking.fmt.Println!?(ch# // ,nce again print .v% ok )$ ?(ch // v is % ok is false.

    n the next example &e let the Pu+lish function return a channel* &hich is used to roadcasta message &hen the text has een pu lished'

    // Pu+lish prints te t to stdout after the given time has e pired.// &t closes the 1ait channel 1hen the te t has +een pu+lished.func Pu+lish!te t string% delay time.Huration# !1ait ?(chan struct{}# { ch )$ make!chan struct{}# go func!# {

    time.Sleep!delay# fmt.Println!te t# close!ch# }!# return ch}

    #his is ho& you might use this Pu+lish function'

    1ait )$ Pu+lish! important ne1s % 5 " time.>inute#// Ho some more 1ork.?(1ait // +locks until the te t has +een pu+lished

    Select statement

    #he select statement is the final tool in Go+s concurrency toolkit' t chooses &hich of a set of possi le communications &ill proceed' f any of the communications can proceed* one ofthem is randomly chosen and the corresponding statements are executed' 4ther&ise* if thereis no default case* the statement locks until one of the communications can complete'

    Here is a toy example sho&ing ho& the select statement can e used to implement a randomnum er generator'

    rand )$ make!chan int#for { // Send random seOuence of +its to rand. select { case rand ?( 3) // note) no statement case rand ?( *) }}

    Some&hat more realistically* here is ho& a select statement could e used to set a time limiton a receive operation'

    select {

    case ne1s )$ ?(FAP) fmt.Println!ne1s#case ?(time.Ffter!time.>inute#)

    -=

  • 8/13/2019 Go for Java Programmers

    17/35

    fmt.Println! Time out) no ne1s in one minute. #}

    #he function time.Ffter is part of the standard li rary1 it &aits for a specified time to elapseand then sends the current time on the returned channel'

    Concurrency (example)

    3e end &ith a small ut complete example to sho& ho& the pieces fit together' t+s draftcode for a server accepting Qork re%uests through a channel' Each re%uest is served in aseparate goroutine' #he Qork struct itself contains a channel used to return a result'

    package server

    import log

    // De1 creates a ne1 server that accepts Qork reOuests// through the reO channel.func De1!# !reO chan?( "Qork# { 1c )$ make!chan "Qork# go serve!1c# return 1c}

    type Qork struct { ,p func!int% int# int F% M int eply chan int // Server sends result on this channel.}

    func serve!1c ?(chan "Qork# { for 1 )$ range 1c { go safelyHo!1# }}

    func safelyHo!1 "Qork# { // egain control of panicking goroutine to avoid // killing the other e ecuting goroutines. defer func!# { if err )$ recover!#4 err I$ nil { log.Println! 1ork failed) % err# } }!# do!1#}

    func do!1 "Qork# { 1. eply ?( 1.,p!1.F% 1.M#}server'go

    /nd this is ho& you might use it'

    package server test

    import !

    ->

    http://www.nada.kth.se/~snilsson/go_for_java_programmers/src/server/server.gohttp://www.nada.kth.se/~snilsson/go_for_java_programmers/src/server/server.go
  • 8/13/2019 Go for Java Programmers

    18/35

    server . fmt time#

    func main!# {

    s )$ server.De1!#

    divideMyRero )$ Nserver.Qork{ ,p) func!a% + int# int { return a / + }% F) *33% M) 3% eply) make!chan int#% } s ?( divideMyRero

    select { case res )$ ?(divideMyRero. eply) fmt.Println!res#

    case ?(time.Ffter!time.Second#) fmt.Println! Do result in one second. # } // ,utput) Do result in one second.}example0test'go

    Concurrent programming is a large topic and Go+s approach is %uite different from $ava+s'Here are t&o texts that cover the asics'

    .undamentals of concurrent programming is a gentle introduction to concurrency &ithsmall examples in Go'

    Share Memory y Communicating is a code&alk &ith a more su stantial example'

    Stefan ilsson

    #his &ork is licensed under a Creative Commons /ttri ution 6'B :nported ;icense '#he text is ased on a similar document for C programmers'2B-6"B-"2A

    -?

    http://www.nada.kth.se/~snilsson/go_for_java_programmers/src/server/example_test.gohttp://www.nada.kth.se/~snilsson/concurrency/http://golang.org/doc/codewalk/sharemem/https://plus.google.com/100350950314702566738/about?rel=authorhttp://creativecommons.org/licenses/by/3.0/http://code.google.com/p/go-wiki/wiki/GoForCPPProgrammershttp://www.nada.kth.se/~snilsson/go_for_java_programmers/src/server/example_test.gohttp://www.nada.kth.se/~snilsson/concurrency/http://golang.org/doc/codewalk/sharemem/https://plus.google.com/100350950314702566738/about?rel=authorhttp://creativecommons.org/licenses/by/3.0/http://code.google.com/p/go-wiki/wiki/GoForCPPProgrammers
  • 8/13/2019 Go for Java Programmers

    19/35

    !undamentals of concurrent programming

    -'#hreads of execution 2' Channels 6' Synchroni ation 8' 7eadlock 9' 7ata races =' Mutual exclusion lock >' 7etecting data races ?' Select statement A' #he mother of all concurrency examples

    -B' Parallel computation

    #his is an introduction to concurrent programming &ith examples in Go ' #he text covers

    concurrent threads of execution (goroutines)* asic synchroni ation techni%ues (channels and locks)* asic concurrency patterns in Go* deadlock and data races* parallel computation'

  • 8/13/2019 Go for Java Programmers

    20/35

    ackground you need' 5ou may also &ant to take a look at either Go for C programmers or Go for $ava programmers '

    ,- # reads of execution

    Go permits starting a ne& thread of execution* a goroutine * using the go statement' t runs afunction in a different* ne&ly created* goroutine' /ll goroutines in a single program share thesame address space'

    Goroutines are light&eight* costing little more than the allocation of stack space' #he stacksstart small and gro& y allocating and freeing heap storage as re%uired' nternally goroutinesare multiplexed onto multiple operating system threads' f one goroutine locks an 4S thread*for example &aiting for input* other goroutines in this thread &ill migrate so that they maycontinue running' 5ou do not have to &orry a out these details'

    #he follo&ing program &ill print =ello from main goroutine ' t might print =ellofrom another goroutine * depending on &hich of the t&o goroutines finish first'

    func main!# { go fmt.Println! =ello from another goroutine # fmt.Println! =ello from main goroutine #

    // Ft this point the program e ecution stops and all // active goroutines are killed.}goroutine-'go

    #he next program &ill* most likely* print oth =ello from main goroutine and =ellofrom another goroutine ' #hey might e printed in any order' 5et another possi ility isthat the second goroutine is extremely slo& and doesn+t print its message efore the programends'

    func main!# { go fmt.Println! =ello from another goroutine # fmt.Println! =ello from main goroutine #

    time.Sleep!time.Second# // 1ait * sec for other goroutine to finish}goroutine2'go

    Here is a some&hat more realistic example* &here &e define a function that uses concurrencyto postpone an event'

    // Pu+lish prints te t to stdout after the given time has e pired.// &t doesn't +lock +ut returns right a1ay.func Pu+lish!te t string% delay time.Huration# { go func!# { time.Sleep!delay# fmt.Println! M 0F &D8 D0QS) % te t# }!# // Dote the parentheses. Qe must call the anonymous function.}

    pu lish-'go

    2B

    http://code.google.com/p/go-wiki/wiki/GoForCPPProgrammershttp://www.nada.kth.se/~snilsson/go_for_java_programmers/http://golang.org/ref/spec#Go_statementshttp://www.nada.kth.se/~snilsson/concurrency/src/goroutine1.gohttp://www.nada.kth.se/~snilsson/concurrency/src/goroutine2.gohttp://www.nada.kth.se/~snilsson/concurrency/src/publish1.gohttp://code.google.com/p/go-wiki/wiki/GoForCPPProgrammershttp://www.nada.kth.se/~snilsson/go_for_java_programmers/http://golang.org/ref/spec#Go_statementshttp://www.nada.kth.se/~snilsson/concurrency/src/goroutine1.gohttp://www.nada.kth.se/~snilsson/concurrency/src/goroutine2.gohttp://www.nada.kth.se/~snilsson/concurrency/src/publish1.go
  • 8/13/2019 Go for Java Programmers

    21/35

    #his is ho& you might use the Pu+lish function'

    func main!# { Pu+lish! F goroutine starts a ne1 thread of e ecution. % 9"time.Second# fmt.Println! Get's hope the ne1s 1ill pu+lished +efore & leave. #

    // Qait for the ne1s to +e pu+lished. time.Sleep!*3 " time.Second#

    fmt.Println! Ten seconds later) &'m leaving no1. #}

    pu lish-'go

    #he program &ill* most likely* print the follo&ing three lines* in the given order and &ith afive second reak in et&een each line'

    go run pu+lish*.goGet's hope the ne1s 1ill pu+lished +efore & leave.M 0F &D8 D0QS) F goroutine starts a ne1 thread of e ecution.Ten seconds later) &'m leaving no1.

    n general it+s not possi le to arrange for threads to &ait for each other y sleeping' n thenext section &e+ll introduce one of Go+s mechanisms for synchroni ation* channels * and then&e+ll demonstrate ho& to use a channel to make one goroutine &ait for another'

    .- C annels

    / channel is a Go language construct that provides a mechanism for t&o goroutines tosynchroni e execution and communicate y passing a value of a specified element type' #he?( operator specifies the channel direction* send or receive' f no direction is given* thechannel is i"directional'

    chan T // can +e used to send and receive values of type Tchan?( float:7 // can only +e used to send float:7s?(chan int // can only +e used to receive ints

    2-

    http://www.nada.kth.se/~snilsson/concurrency/src/publish1.gohttp://golang.org/ref/spec#Channel_typeshttp://www.flickr.com/photos/erikjaeger/35008017/http://www.nada.kth.se/~snilsson/concurrency/src/publish1.gohttp://golang.org/ref/spec#Channel_types
  • 8/13/2019 Go for Java Programmers

    22/35

    Channels are a reference type and are allocated &ith make'

    ic )$ make!chan int# // un+uffered channel of ints1c )$ make!chan "Qork% *3# // +uffered channel of pointers to Qork

    #o send a value on a channel* use ?( as a inary operator' #o receive a value on a channel*use it as a unary operator'

    ic ?( 6 // Send 6 on the channel.1ork )$ ?(1c // eceive a pointer to Qork from the channel.

    f the channel is un uffered* the sender locks until the receiver has received the value' f thechannel has a uffer* the sender locks only until the value has een copied to the uffer1 ifthe uffer is full* this means &aiting until some receiver has retrieved a value' Deceivers

    lock until there is data to receive'

    Close#he close function records that no more values &ill e sent on a channel' /fter callingclose * and after any previously sent values have een received* receive operations &ill returna ero value &ithout locking' / multi"valued receive operation additionally returns a

    oolean indicating &hether the channel is closed'

    ch )$ make!chan string#go func!# { ch ?( =elloI close!ch#}!#fmt.Println!?(ch# // prints =elloIfmt.Println!?(ch# // prints the zero value 1ithout +lockingfmt.Println!?(ch# // once again prints v% ok )$ ?(ch // v is % ok is false

    /- Sync roni0ation

    n the next example &e let the Pu+lish function return a channel* &hich is used to roadcasta message &hen the text has een pu lished'

    // Pu+lish prints te t to stdout after the given time has e pired.

    // &t closes the 1ait channel 1hen the te t has +een pu+lished.func Pu+lish!te t string% delay time.Huration# !1ait ?(chan struct{}# { ch )$ make!chan struct{}# go func!# { time.Sleep!delay# fmt.Println! M 0F &D8 D0QS) % te t# close!ch# // +roadcast U a closed channel sends a zero valueforever }!# return ch}

    pu lish2'go

    #his is ho& you might use the function'

    22

    http://golang.org/ref/spec#Closehttp://www.nada.kth.se/~snilsson/concurrency/src/publish2.gohttp://golang.org/ref/spec#Closehttp://www.nada.kth.se/~snilsson/concurrency/src/publish2.go
  • 8/13/2019 Go for Java Programmers

    23/35

    func main!# { 1ait )$ Pu+lish! ;hannels let goroutines communicate. % 9"time.Second# fmt.Println! Qaiting for the ne1s... # ?(1ait fmt.Println! The ne1s is out% time to leave. #}

    pu lish2'go

    #he program &ill print the follo&ing three lines in the given order' #he final line is printedimmediately after the ne&s is out'

    go run pu+lish5.goQaiting for the ne1s...M 0F &D8 D0QS) ;hannels let goroutines communicate.The ne1s is out% time to leave.

    1- Deadlock

    ;et+s introduce a ug in the Pu+lish function!

    func Pu+lish!te t string% delay time.Huration# !1ait ?(chan struct{}# { ch )$ make!chan struct{}# go func!# { time.Sleep!delay# fmt.Println! M 0F &D8 D0QS) % te t# //close(ch) }!# return ch}

    #he main program starts like efore! it prints the first line and then &aits for five seconds' /t

    this point the goroutine started y the Pu+lish function &ill print the reaking ne&s and thenexit leaving the main goroutine &aiting'

    26

    http://www.nada.kth.se/~snilsson/concurrency/src/publish2.gohttp://www.flickr.com/photos/lasgalletas/263909727/http://www.nada.kth.se/~snilsson/concurrency/src/publish2.go
  • 8/13/2019 Go for Java Programmers

    24/35

    func main!# { 1ait )$ Pu+lish! ;hannels let goroutines communicate. % 9"time.Second# fmt.Println! Qaiting for the ne1s... #

  • 8/13/2019 Go for Java Programmers

    25/35

    }!# n++ // another conflicting access ?(1ait fmt.Println!n# // ,utput) VDSP0;&A&0H}datarace'go

    #he t&o goroutines* g* and g5 * participate in a race and there is no &ay to kno& in &hichorder the operations &ill take place' #he follo&ing is one out of many possi le outcomes'

    g* reads the value 3 from n ' g5 reads the value 3 from n ' g* increments its value from 3 to * ' g* &rites * to n ' g5 increments its value from 3 to * ' g5 &rites * to n '

    #he programs prints the value of n* &hich is no& * '

    #he name data race is some&hat misleading' ot only is the ordering of operationsundefined1 there are no guarantees whatsoever '

  • 8/13/2019 Go for Java Programmers

    26/35

    #he only &ay to avoid data races is to synchroni e access to all muta le data that is shared et&een threads' #here are several &ays to achieve this' n Go* you &ould normally use achannel or a lock' (;o&er"lever mechanisms are availa le in the sync and sync/atomic

    packages* ut are not discussed in this text')

    #he preferred &ay to handle concurrent data access in Go is to use a channel to pass theactual data from one goroutine to the next' #he motto is! 7on+t communicate y sharingmemory1 share memory y communicating'

    func sharing&s;aring!# { ch )$ make!chan int# go func!# { n )$ 3 // F local varia+le is only visi+le to one goroutine. nCC ch ?( n // The data leaves one goroutine... }!# n )$ ?(ch // ...and arrives safely in another goroutine.

    nCC fmt.Println!n# // ,utput) 5}datarace'go

    n this code the channel does dou le duty' t passes the data from one goroutine to anotherand it acts as a point of synchroni ation! the sending goroutine &ill &ait for the othergoroutine to receive the data and the receiving goroutine &ill &ait for the other goroutine tosend the data'

    #he Go memory model the conditions under &hich reads of a varia le in one goroutine can

    e guaranteed to o serve values produced y &rites to the same varia le in a differentgoroutine is %uite complicated* ut as long as you share all muta le data et&eengoroutines through channels you are safe from data races'

    3- "utual exclusion lock

    Sometimes it+s more convenient to synchroni e data access y explicit locking instead ofusing channels' #he Go standard li rary offers a mutual exclusion lock* sync'Mutex * for this

    purpose'

    .or this type of locking to &ork* it+s crucial that all accesses to the shared data* oth readsand &rites* are performed only &hen a goroutine holds the lock' 4ne mistake y a singlegoroutine is enough to reak the program and introduce a data race'

    2=

    http://golang.org/pkg/sync/http://golang.org/pkg/sync/atomic/http://golang.org/pkg/sync/atomic/http://www.nada.kth.se/~snilsson/concurrency/src/datarace.gohttp://golang.org/ref/memhttp://golang.org/ref/memhttp://golang.org/pkg/sync/#Mutexhttp://www.flickr.com/photos/dzarro72/7187334179/http://golang.org/pkg/sync/http://golang.org/pkg/sync/atomic/http://www.nada.kth.se/~snilsson/concurrency/src/datarace.gohttp://golang.org/ref/memhttp://golang.org/pkg/sync/#Mutex
  • 8/13/2019 Go for Java Programmers

    27/35

    http://www.nada.kth.se/~snilsson/concurrency/src/datarace.gohttp://golang.org/pkg/sync/#WaitGrouphttp://www.nada.kth.se/~snilsson/concurrency/src/datarace.gohttp://golang.org/pkg/sync/#WaitGroup
  • 8/13/2019 Go for Java Programmers

    28/35

    1g.Qait!# // Qait for all five goroutines to finish. fmt.Println!#}raceClosure'go

    / plausi le explanation for the 99999 output is that the goroutine that executes iCC managedto do this five times efore any of the other goroutines executed their print statements' #hefact that the updated value of i &as visi le to the other goroutines is purely coincidental'

    / simple solution is to use a local varia le and pass the num er as a parameter &hen startingthe goroutine'

    func correct!# { var 1g sync.Qait8roup 1g.Fdd!9# for i )$ 34 i ? 94 iCC { go func!n int# { // Vse a local varia+le.

    fmt.Print!n# 1g.Hone!# }!i# } 1g.Qait!# fmt.Println!#}raceClosure'go

    #his code is correct and the program prints an expected result* such as 5736* ' Decall that theorder of execution et&een goroutines is unspecified and may vary'

    t+s also possi le to avoid this data race &hile still using a closure* ut then &e must take careto use a uni%ue varia le for each goroutine'

    func also;orrect!# { var 1g sync.Qait8roup 1g.Fdd!9# for i )$ 34 i ? 94 iCC { n )$ i // ;reate a uniOue varia+le for each closure. go func!# { fmt.Print!n# 1g.Hone!# }!# } 1g.Qait!# fmt.Println!#}raceClosure'go

    Automatic data race detection

    n general* it+s not possi le to automatically detect all data races' Ho&ever* Go -'- &ill come&ith a po&erful data race detector ' :nfortunately* it+s not availa le &ith Go -'B'6' t you&ant to try it out* the command

    hg clone https)//code.google.com/p/go

    2?

    http://www.nada.kth.se/~snilsson/concurrency/src/raceClosure.gohttp://www.nada.kth.se/~snilsson/concurrency/src/raceClosure.gohttp://www.nada.kth.se/~snilsson/concurrency/src/raceClosure.gohttp://tip.golang.org/doc/articles/race_detector.htmlhttp://www.nada.kth.se/~snilsson/concurrency/src/raceClosure.gohttp://www.nada.kth.se/~snilsson/concurrency/src/raceClosure.gohttp://www.nada.kth.se/~snilsson/concurrency/src/raceClosure.gohttp://tip.golang.org/doc/articles/race_detector.html
  • 8/13/2019 Go for Java Programmers

    29/35

    &ill fetch the latest Go source code* &hich you+ll then need to compile and install '

    #he tool is simple to use! ,ust add the (race flag to the go command' Dunning the programa ove &ith the detector turned on gives the follo&ing clear and informative output'

    go run (race race;losure.goace)$$$$$$$$$$$$$$$$$$QF D&D8) HFTF F;0

    ead +y goroutine 5) main.funcW33*!# ../race;losure.go)55 C3 :9

    Previous 1rite +y goroutine 3) main.race!# ../race;losure.go)53 C3 *B+ main.main!# ../race;losure.go)*3 C3 5B

    runtime.main!# ../go/src/pkg/runtime/proc.c)57@ C3 B*

    8oroutine 5 !running# created at) main.race!# ../race;losure.go)57 C3 *@+ main.main!# ../race;losure.go)*3 C3 5B runtime.main!# ../go/src/pkg/runtime/proc.c)57@ C3 B*

    $$$$$$$$$$$$$$$$$$99999

    ;orrect)3*567Flso correct)3*657Aound * data race!s#e it status ::

    #he tool found a data race consisting of a &rite to a varia le on line 2B in one goroutine*follo&ed y an unsynchroni ed read from the same varia le on line 22 in another goroutine'

    ote that the race detector only finds data races that actually happen during execution'

    5- Select statement

    #he select statement is the final tool in Go+s concurrency toolkit' t chooses &hich of a set of possi le communications &ill proceed' f any of the communications can proceed* one ofthem is randomly chosen and the corresponding statements are executed' 4ther&ise* if thereis no default case* the statement locks until one of the communications can complete'

    Here is a toy example sho&ing ho& the select statement can e used to implement a randomnum er generator'

    // andomMits returns a channel that produces a random seOuence of +its.func andomMits!# ?(chan int { ch )$ make!chan int#

    2A

    http://golang.org/doc/install/sourcehttp://golang.org/doc/install/sourcehttp://golang.org/ref/spec#Select_statementshttp://golang.org/doc/install/sourcehttp://golang.org/ref/spec#Select_statements
  • 8/13/2019 Go for Java Programmers

    30/35

    go func!# { for { select { case ch ?( 3) // note) no statement case ch ?( *) }

    } }!# return ch}rand

  • 8/13/2019 Go for Java Programmers

    31/35

    } 1g.Qait!# select { case name )$ ?(match) fmt.Printf! Do one received Xs's message.Yn % name# default)

    // There 1as no pending send operation. }}

    // Seek either sends or receives% 1hichever possi+le% a name on the match// channel and notifies the 1ait group 1hen done.func Seek!name string% match chan string% 1g "sync.Qait8roup# { select { case peer )$ ?(match) fmt.Printf! Xs sent a message to Xs.Yn % peer% name# case match ?( name) // Qait for someone to receive my message. }

    1g.Hone!#}matching'go

    Example output!

    go run matching.go;ody sent a message to Mo+.Fnna sent a message to 0va.Do one received Have's message.

    ,7- arallel computation

    4ne application of concurrency is to divide a large computation into &ork units that can escheduled for simultaneous computation on separate CP:s'

    7istri uting computations onto several CP:s is more of an art than a science' Here are somerules of thum '

    Each &ork unit should take a out -BBIs to -ms to compute' f the units are too small*the administrative overhead of dividing the pro lem and scheduling su "pro lemsmight e too large' f the units are too ig* the &hole computation may have to &ait

    for a single slo& &ork item to finish' #his slo&do&n can happen for many reasons*

    6-

    http://www.nada.kth.se/~snilsson/concurrency/src/matching.gohttp://www.flickr.com/photos/somegeekintn/4819945812/http://www.nada.kth.se/~snilsson/concurrency/src/matching.go
  • 8/13/2019 Go for Java Programmers

    32/35

    such as scheduling* interrupts from other processes* and unfortunate memory layout'( ote that the num er of &ork units is independent of the num er of CP:s')

    #ry to minimi e the amount of data sharing' Concurrent &rites can e very costly* particularly so if goroutines execute on separate CP:s' Sharing data for reading isoften much less of a pro lem'

    Strive for good locality &hen accessing data' f data can e kept in cache memory*data loading and storing &ill e dramatically faster' 4nce again* this is particularlyimportant for &riting'

    #he follo&ing example sho&s ho& to divide a costly computation and distri ute it on allavaila le CP:s' #he idea is simple! identify &ork units of suita le si e and then run each&ork unit in a separate goroutine'

    type Eector []float:7

    // ;onvolve computes 1 $ u " v% 1here 1[k] $ Z u[i]"v[-]% i C - $ k.

    // Precondition) len!u# 2 3% len!v# 2 3.func ;onvolve!u% v Eector# !1 Eector# { n )$ len!u# C len!v# ( * 1 $ make!Eector% n#

    // Hivide 1 into 1ork units that take *33\s(*ms to compute. size )$ ma !*% *??53/n#

    1g )$ ne1!sync.Qait8roup# 1g.Fdd!* C !n(*#/size# for i )$ 34 i ? n NN i 2$ 34 i C$ size { // i ? 3 after int overflo1 - )$ i C size if - 2 n JJ - ? 3 { // - ? 3 after int overflo1 - $ n } // These goroutines share memory% +ut only for reading. go func!i% - int# { for k )$ i4 k ? -4 kCC { 1[k] $ mul!u% v% k# // 1[k] $ Z u[i]"v[-]% i C - $ k } 1g.Hone!# }!i% -# } 1g.Qait!# return}

    convolution'go

    3hen the &ork units have een defined* it+s often est to leave the scheduling to the runtimeand the operating system' Ho&ever* &ith Go -'B'6 you need to tell the runtime ho& manygoroutines you &ant executing code simultaneously'

    func init!# { numcpu )$ runtime.Dum;PV!# runtime.8,>F P ,;S!numcpu# // Try to use all availa+le ;PVs.}

    Stefan ilsson

    62

    http://www.nada.kth.se/~snilsson/concurrency/src/convolution.gohttps://plus.google.com/100350950314702566738/about?rel=authorhttp://www.nada.kth.se/~snilsson/concurrency/src/convolution.gohttps://plus.google.com/100350950314702566738/about?rel=author
  • 8/13/2019 Go for Java Programmers

    33/35

    #his &ork is licensed under a Creative Commons /ttri ution 6'B :nported ;icense '2B-6"B2"B9

    66

    http://creativecommons.org/licenses/by/3.0/http://creativecommons.org/licenses/by/3.0/
  • 8/13/2019 Go for Java Programmers

    34/35

    // ;opyright 53*3 The 8o Futhors. Fll rights reserved.// Vse of this source code is governed +y a MSH(style// license that can +e found in the G&;0DS0 file.

    package main

    import ! lognet/httptime

    #

    const !numPollers $ 5 // num+er of Poller goroutines to

    launchpoll&nterval $ :3 " time.Second // ho1 often to poll each V Gstatus&nterval $ *3 " time.Second // ho1 often to log status to

    stdouterrTimeout $ *3 " time.Second // +ack(off timeout on error

    #var urls $ []string{

    http)//111.google.com/ %http)//golang.org/ %http)//+log.golang.org/ %

    }

    // State represents the last(kno1n state of a V G.type State struct {

    url stringstatus string

    }

    // State>onitor maintains a map that stores the state of the V Gs +eing// polled% and prints the current state every update&nterval nanoseconds.// &t returns a chan State to 1hich resource state should +e sent.func State>onitor!update&nterval time.Huration# chan?( State {

    updates )$ make!chan State#urlStatus )$ make!map[string]string#ticker )$ time.De1Ticker!update&nterval#go func!# {

    for {select {case ?(ticker.;)

    logState!urlStatus#case s )$ ?(updates)

    urlStatus[s.url] $ s.status}

    }}!#return updates

    }

    // logState prints a state map.func logState!s map[string]string# {

    log.Println! ;urrent state) #for k% v )$ range s {

    log.Printf! Xs Xs % k% v#}

    }

    68

  • 8/13/2019 Go for Java Programmers

    35/35

    // esource represents an =TTP V G to +e polled +y this program.type esource struct {

    url stringerr;ount int

    }

    // Poll e ecutes an =TTP =0FH reOuest for url// and returns the =TTP status string or an error string.func !r " esource# Poll!# string {

    resp% err )$ http.=ead!r.url#if err I$ nil {

    log.Println! 0rror % r.url% err#r.err;ountCCreturn err.0rror!#

    }r.err;ount $ 3return resp.Status

    }

    // Sleep sleeps for an appropriate interval !dependant on error state#// +efore sending the esource to done.func !r " esource# Sleep!done chan?( " esource# {

    time.Sleep!poll&nterval C errTimeout"time.Huration!r.err;ount##done ?( r

    }

    func Poller!in ?(chan " esource% out chan?( " esource% status chan?( State#{

    for r )$ range in {s )$ r.Poll!#status ?( State{r.url% s}out ?( r

    }}

    func main!# {// ;reate our input and output channels.pending% complete )$ make!chan " esource#% make!chan " esource#

    // Gaunch the State>onitor.status )$ State>onitor!status&nterval#

    // Gaunch some Poller goroutines.for i )$ 34 i ? numPollers4 iCC {

    go Poller!pending% complete% status#}

    // Send some esources to the pending Oueue.go func!# {

    for % url )$ range urls {pending ?( N esource{url) url}

    }}!#

    for r )$ range complete {go r.Sleep!pending#

    }}