Go, the brand-spanking new language from Google that arrived November 10, 2009, is a compiled, concurrent, threaded systems language — the first systems language of this decade!
The intent was to produce a language that had performance comparable to C, but developer satisfaction comparable to that of Python or Ruby. The language features some impressive ideas, including type inference, shorthand for declaration, initialization, and assignment, and interfaces, but I’d like to talk about my favorite features – Go routines and channels.
“Hey Joey, look at the f***in’ tubes!”
~George Carlin

Go Routines
Rather than using threads, Go supplies a mechanism called a Go routine. While these operate in a similar manner to threads, they have the benefit of being load-balanced internally across real threads by the Go language.
func threadedThing(){
// Do some stuff
}
func main() {
go threadedThing();
// Continue without blocking!
}
Go routines can also be declared anonymously, like so:
func main() {
go func() {
// Do some stuff
}(); // <- parentheses to call the function
// Continue without blocking!
}
Channels (Tubes)
Go calls them channels, I call them tubes! Channels form the basis of how we can communicate between Go routines. Take the following example:
func printer(input chan int){
var a int;
for {
a <- input;
fmt.println("Receieved: ",a);
}
}
func main() {
tube := make(chan int);
go printer(tube);
for i:=0; i < 10; i++ {
tube <- i;
}
}
In the above example, the printer will block until it receives an item from the input channel (a <- input), and then print it out. Meanwhile, the main send values through the channel (tube <- i) - and it also blocks. However, if we change the declaration of the channel to include a buffer...
tube := make(chan int, 10)
...the main can continue to loop, simply dropping things into the channel buffer.
When is a tube not a tube?
Consider the following example:
func main() {
killswitch := make(chan int);
go server(killswitch);
// Do some work
<- killswitch;
}
Here we see an example of how you might "join" another "thread", but in Go terms. Rather than using the channel to communicate data, we simply await any communication from the channel, and then quit. Since reading from the channel is a blocking operation, the server Go routine can simply write any value to the killswitch channel, and the main will read it, discard it, and terminate.
Channels can be used for a variety of different purposes - to transmit data, to acts as a termination signal, and even as semaphores. The flexibility of a language like Go makes it a treat to work with, and I encourage you to head over to http://golang.org and take a look for yourself!