Concurrency is a composition of independently computing things.
Parallelism is a simultaniuse execution of multiple things.
Concurrency is about dealing with lots of things at once.
Parallelism is about doing lots of things at once.
Rob Pike, "Concurrency Is Not Parallelism", 2012
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());
}
}
class Counter {
private int count = 0;
public synchronized void increment() { ++count; }
public int getCount() { return count; }
}
(defn reduce-sum [numbers]
(reduce (fn [acc x] (+ acc x)) 0 numbers))
(defn sum [numbers]
(reduce + numbers))
(ns sum.core
(:require [clojure.core.reducers :as r]))
(defn parallel-sum [numbers]
(r/fold + numbers))
(defn count-words-sequential [pages]
(frequencies (mapcat get-words pages)))
(pmap #(frequencies (get-words %)) pages)
(defn count-words-parallel [pages]
(reduce (partial merge-with +)
(pmap #(frequencies (get-words %)) pages)))
(ns sum.core
(:require [clojure.core.reducers :as r]))
(defn parallel-sum [numbers]
(r/fold + numbers))
(+ (+ 1 2) (+ 3 4)) → (+ (+ 1 2) 7) → (+ 3 7) → 10
(+ (+ 1 2) (+ 3 4)) → (+ 3 (+ 3 4)) → (+ 3 7) → 10
(defn transfer [from to amount]
(dosync
(alter from - amount)
(alter to + amount)))
=> (def user1 (ref 1000))
=> (def user2 (ref 2000))
=> (transfer user2 user1 100)
1100
=> @checking
1100
=> @savings
1900
defmodule Talker do
def loop do
receive do
{:greet, name} -> IO.puts("Hello, #{name}")
{:bye, status, name} -> IO.puts("Bye, #{status} #{name}")
end
loop
end
end
pid = spawn(&Talker.loop/0)
send(pid, {:greet, "Gopher"})
send(pid, {:bye, "Mrs", "Pike"})
sleep(1000)
Hello, Gopher
Bye, Mrs Pike
Do not communicate by sharing memory, instead share memory by communicating
Rob Pike
go func()
Just looked at a Google-internal Go server with 139K goroutines serving over 68K active network connections. Concurrency wins.
@rob_pike
// Declaring and initializing
var ch chan int
ch = make(chan int)
// or
ch := make(chan int)
// Buffering
ch := make(chan int, 100)
// Sending on a channel
ch <- 1
// Receiving from a channel
value = <- ch
func main() {
jobs := make(chan Job)
done := make(chan bool, len(jobList))
go func() {
for _, job := range jobList {
jobs <- job // Blocks waiting for a receive
}
close(jobs)
}()
go func() {
for job := range jobs { // Blocks waiting for a send
fmt.Println(job) // Do one job
done <- true
}
}()
for i := 0; i < len(jobList); i++ {
<-done // Blocks waiting for a receive
}
}
Source: https://github.com/vaxXxa/talks