Logo

Programming-Idioms

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

Be concise.

Be useful.

All contributions dictatorially edited by webmasters to match personal tastes.

Please do not paste any copyright violating material.

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

Other implementations
(def x (atom 0))
(def f inc)
(swap! x f)
#include <mutex>
//declaration
auto mutex = std::mutex{};
auto x = someValue();

//use
{
	auto lock = std::unique_lock{mutex};
	x = f(x);
}
#include <atomic>
std::atomic<int> x{};

auto local_x = x.load();
while(!x.compare_exchange_strong(local_x, f(local_x))) {
	local_x = x.load();
}
private readonly object m_Sync = new object();

lock(m_Sync)
{
    x = f(x);
}
lock (x) {
  x = f(x);	
}
synchronized x = f(x);
x = f(x);
x = f(x)
integer, dimension[*] :: x

critical
  x = f(x)
end critical
import "sync"
var lock sync.Mutex

lock.Lock()
x = f(x)
lock.Unlock()
import Control.Concurrent.MVar
putMVar x . f =<< takeMVar x
let x = f(x)
synchronized(lock){
  x = f(x);
}
volatile T x;
class Example<T> {
    T x;
    Object lock = new Object();
    T read() {
        synchronized (lock) {
            return x;
        }
    }
    void write(T x) {
        synchronized (lock) {
            this.x = 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()
import threading
with threading.Lock():
    x = f(x)
require 'atomic'
x = Atomic.new(0)
x.update { |x| f(x) }
let mut x = x.lock().unwrap();
*x = f(x);