Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's Java's equivalent of .Net's Interlocked class?

How do I modify an int atomically and thread-safely in Java?

Atomically increment, test & set, etc...?

like image 794
ripper234 Avatar asked Jul 20 '09 08:07

ripper234


People also ask

When should you use the interlocked class?

The methods of this class help protect against errors that can occur when the scheduler switches contexts while a thread is updating a variable that can be accessed by other threads, or when two threads are executing concurrently on separate processors.

What is interlocked exchange?

Interlock. Exchange returns the original value while performing an atomic operation. The whole point is to provide a locking mechanism. So it is actually two operations: read original value and set new value.


2 Answers

Use AtomicInteger.

like image 138
Bombe Avatar answered Sep 18 '22 17:09

Bombe


Thread safety can be achieved via synchronized functions. Wrap your int (or such data) in a class which provides the required functionalities via synchronized methods, e.g.

public class X
{
  protected int x;
  public synchronized void set( int value )
  {
    x = value;
  }
}

You can also use classes from the java.util.concurrent.atomic package, e.g. AtomicInteger or AtomicIntegerArray

Why this answer won't work

I just wanted to be sure to point out exactly what is wrong with this answer, in case anyone things that synchronized can be used to solve thread race effects

| Thread A      | Thread B         | 
|---------------|------------------|
| read x (x=4)  |                  |
|               | read x (x=4)     |
| Calculate 4+1 |                  |
| EAX ← 5       |                  |
|               | Calculate 4+1    |
|               | EAX ← 5          |
| Start sync    |                  |
| {             | Start sync       |
| { x ← 5       |    wait          |
| {             |    wait          |
| End sync      |    wait          |
|               | {                | 
|               | { x ← 5          |
|               | {                | 
|               | End sync         |

The end result of the operations:

x = 4;
x += 1;
x += 1;

is that x = 5 rather than 6.

The same issue exists with the volatile keyword. The volatile keyword doesn't save you from thread effects. The volatile keyword only ensures that

  • caches are flushed before a variable is read
  • caches are flushed after a value is written

Strictly speaking, volatile ensures that memory operations are not reordered around a volatile variable. Which means you still suffer from the:

  • read from x
  • write to x

problem.

like image 20
CsTamas Avatar answered Sep 21 '22 17:09

CsTamas