Implementation
Haskell

Be concise.

Be useful.

All contributions dictatorially edited by webmasters to match personal tastes.

Please do not paste any copyright violating resource.

Please try to avoid dependencies to third-party libraries and frameworks.

Other implementations
import "sync"
var wg sync.WaitGroup
wg.Add(1000)
for i := 1; i <= 1000; i++ {
	go func(i int) {
		f(i)
		wg.Done()
	}(i)
}
wg.Wait()
fmt.Println("Finished")
import java.util.concurrent.*;
class Task implements Runnable {
	int i;
	Task(int i) {
		this.i = i;
	}
	@Override
	public void run() {
		f(i);
	}
}

ExecutorService executor = Executors.newFixedThreadPool(4);
for (int i = 1; i <= 1000; i++) {
	Task task = new Task(i);
	executor.submit(task);
}
executor.awaitTermination(10L, TimeUnit.MINUTES);
System.out.println("Finished");
use threads;
for my $i (1 .. 1000) {
    threads->create('f', $i);
}
sleep 3 while threads->list(threads::running);
print "Finished\n";

# optional: threads library wants you to explicitly join or detach
# your threads before exiting program.
$_->join() for threads->list(threads::joinable);
use std::thread;
let threads: Vec<_> = (0..1000).map(|i| thread::spawn(move || f(i))).collect();

for t in threads {
	t.join();
}
import std.stdio;
import std.parallelism;
import std.range;
foreach(i; parallel(iota(1,1001))){
	f(i);
}
writeln("Finished");
run_n_times(Fun, N) ->
    Self = self(),
    Task = fun (I) -> spawn(?MODULE, run_task_and_notify_completion, [Self, Fun, I]) end,
    lists:foreach(Task, lists:seq(1, N)),
    wait_for_n_tasks(N).

run_task_and_notify_completion(ParentPid, Fun, Arg) ->
    Fun(Arg),
    ParentPid ! done.

wait_for_n_tasks(0) ->
    io:format("Finished~n");
wait_for_n_tasks(N) when N > 0 ->
    receive
        done ->
            ok
    end,
    wait_for_n_tasks(N-1).

run_n_times(F, 1000).
threads = 1000.times.map do |i|
  Thread.new { f(i) }
end
threads.join
from multiprocessing import Pool
def f(i):
	i * i

with Pool(processes) as p:
	p.map(func=f, iterable=range(1, 1001))

print('Finished')
{
  // in file worker.js
  onmessage = f
}
{
  // in file main.js
  for (let i = 0; i < 1000; i++) {
    new Worker ('worker.js')
      .postMessage (i)
  }
}
import kotlinx.coroutines.*
(1..1000)
    .map { i ->
        CoroutineScope(Dispatchers.Default).async {
            f(i)
        }
    }
    .awaitAll()
print("Finished")
using System.Threading.Tasks;
int numTasks = 1000;
Task<int>[] output = new System.Threading.Tasks.Task<int>[numTasks];
for (int i = 0; i < numTasks; i++)
{
  output[i] = Task.Factory.StartNew(
                   new Func <object, int>(LongRunningOperation), 2000);
}
Task.WaitAll(output);

int LongRunningOperation(object objMs)
{
  int ms = (int)objMs;
  Thread.Sleep(ms);
  return ms;
}
# 1
f = &(IO.puts(&1)) 

# 2
printTimes = &(n <- 1..&1, do: spawn(fn -> f.(n) end))

# 3
fn -> printTimes.(1000) end |> Task.async |> Task.await
IO.puts("Finished")