This language bar is your friend. Select your favorite languages!

Idiom #33 Atomically read and update variable

Assign variable x the new value f(x), making sure that no other thread may modify x between the read and the write.

synchronized x = f(x);
x = f(x);
import "sync"
var lock sync.RWMutex

lock.Lock()
x = f(x)
lock.Unlock()
import Control.Concurrent.MVar
putMVar x . f =<< takeMVar x
synchronized(lock){
  x = f(x);
}
$mutex = Mutex::create();
Mutex::lock($mutex);
$x = f($x);
Mutex::unlock($mutex);
Mutex::destroy($mutex);
uses syncobjs;
var
  loc: TCriticalSection;
begin
  loc.Enter;
  try
    x := f(x);
  finally
    loc.Leave;
  end;
end.
use threads;
use threads::shared;
my $x :shared;
$x = 0;

sub my_task {
   my $id = shift;
   for (1 .. 5) {
      sleep 2*rand();
      { # lock scope
         lock($x);
         print "thread $id found $x\n";
         $x = $id;
         sleep 2*rand();
      }
   }
}

threads->create('my_task', $_) for 1 .. 3;
sleep 5 while threads->list(threads::running);
import threading
lock = threading.Lock()

lock.acquire()
try:
	x = f(x)
finally:
	lock.release()
require 'atomic'
x = Atomic.new(0)
x.update { |x| f(x) }
let mut x = x.lock().unwrap();
*x = f(x);

Do you know the best way to do this in your language ?
New implementation...

Idiom created by

programming-idioms.org