// F# program illustrating asynchronous workflows, thread synchronization. open System;; open System.Threading;; // Needed for synchronization primitives // rename some system functions so they're easier to type: let runsync = Async.RunSynchronously;; let runasync = Async.Start;; // Async.StartImmediate will still use same OS thread let runtask = Async.StartAsTask;; // preferred method of starting threads let mutable x = 0;; // shared variable between threads (external state) let syncobject = Object();; // arbitrary object for synchronization let thread1 = async { for i = 1 to 1000 do // Monitor.Enter(syncobject); printf "thread1: x is now %d. " x; x <- x+20; for zzz = 1 to 100000 do // intensional delay loop (note identation) x <- x+1; x <- x-1; // Monitor.Exit(syncobject); };; let thread2 = async { for j = 1 to 1000 do printf "thread2: x is now %d.\n" x; Monitor.Enter(syncobject); x <- x+3; // "critical section" Monitor.Exit(syncobject); };; let task1 = runtask thread1;; // task1 is a handle on task let task2 = runtask thread2;; task1.Wait();; task2.Wait();; // do not exit program until tasks are complete (* for j = 1 to 1000 do printf "main thread: x is now %d.\n" x; x <- x+x; *)