什么是Java相当于.Net的Interlocked类?

时间:2009-07-20 08:25:06

标签: java multithreading concurrency interlocked

如何在Java中原子地和线程安全地修改int?

原子增量,测试&等等......?

3 个答案:

答案 0 :(得分:28)

使用AtomicInteger

答案 1 :(得分:1)

可以通过同步功能实现线程安全。 将int(或此类数据)包装在一个类中,该类通过同步方法提供所需的功能,例如

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

您还可以使用java.util.concurrent.atomic包中的类,例如AtomicInteger或AtomicIntegerArray

为什么这个答案不起作用

我只是想确定指出这个答案的确切错误,以防synchronized可以用来解决线程争用效果的任何事情

| 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         |

操作的最终结果:

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

x = 5 而不是6。

volatile关键字存在同样的问题。 volatile关键字不会使您免受线程影响。 volatile关键字仅确保

  • 在读取变量之前刷新缓存
  • 在写入值后刷新缓存

严格地说,volatile确保内存操作不会在volatile变量周围重新排序。这意味着您仍然受到以下情况的影响:

  • 从x
  • 读取
  • 写给x

问题。

答案 2 :(得分:0)

private final static AtomicInteger at = new AtomicInteger();

public void run() {
    at.set(7);
    int i = at.incrementAndGet();