Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/390.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 比较并交换不正确的值_Java_Concurrency_Locking_Atomic - Fatal编程技术网

Java 比较并交换不正确的值

Java 比较并交换不正确的值,java,concurrency,locking,atomic,Java,Concurrency,Locking,Atomic,我有以下代码用于锁定具有特定用户ID的对象 public boolean acquireLock(Long id) { if (lock.compareAndSet(0L, id)) { return true ; } return false ; } 我通过以下方式获得: while(!parent.acquireLock(id)){ System.out.println(lock.get()); if (count+

我有以下代码用于锁定具有特定用户ID的对象

 public boolean acquireLock(Long id) {
   if (lock.compareAndSet(0L, id)) { 
    return true ; 
  }
  return false ; 
}
我通过以下方式获得:

      while(!parent.acquireLock(id)){
        System.out.println(lock.get());
        if (count++>1000000) {
          System.out.println(id + " Trying to acquire " + lock.get());
          DebugHandler.createException("Error, deadlock");

        }
      }
发布为:

public boolean releaseLock(Long id) { 

  if (lock.compareAndSet(id, 0)) {
    System.out.println("Releasing Lock for " + id);
    return true ; 
  }
  else { 
    DebugHandler.createException("Lock not owned by current view. Thief");
    return false ;
  }

}
并将锁对象声明为:

 private volatile AtomicLong lo = new AtomicLong(0); 
除此之外,我得到了以下奇怪的行为和僵局,其结论是:

Id 45正在尝试获取0

Ak,锁的值是0,但比较和交换测试失败,认为它不是0。(用于测试死锁的计数器在我退出循环后重新初始化)


有什么想法吗?

我发现你的代码有问题。如果某个线程的
id
为零,那么锁定方案将崩溃,两个线程可能会同时持有锁

修正:在
acquireLock
releaseLock
方法中添加防御检查,以测试
id
是否为非零

至于您的代码如何进入明显的死锁状态:

  • 这可能真的是一个真正的僵局。例如,如果线程试图获取给定
    id
    的锁,而它已经持有该
    id
    的锁,则可能会发生这种情况。(实现的锁是不可重入的。)

  • 您的代码可能无法释放给定
    id
    的锁;e、 g.因为引发了异常,并且跳过了对
    releaseLock
    的正常调用


在获取锁时,您在代码中使用的是
this.getWorldID()
,但您的日志使用的是
this.id
。请修复此问题并重新测试,然后让我们知道结果是什么。它真的总是0吗?有时可以预期它为0。这并不意味着死锁,只是自旋锁由另一条线程持有
AtomicLong
是原子的,但它没有阻塞。您是否记得在成功时将
count
设置为0?是的,它始终为0,至少在1000000次迭代中。我确实重置了计数。您正在调用
parent.acquireLock()
,但正在打印
lock.get()
。那些是同一把锁吗
parent.lock
看起来更像您正在寻找的锁。ID在1开始分配时不是0。调试输出显示,非0 id线程试图获取值为0的锁,但CaS测试仍然失败。1)无论如何,您应该包括
0
的防御检查。2) CaS测试失败的原因是锁已经被其他东西持有。我给了你两种可能的解释。可能还有其他人。