java - 等待/通知死锁

标签 java multithreading deadlock wait

我有一个队列,在“添加”和“获取”方法中有一些阻塞机制,其中第一个线程添加数据,第二个线程获取数据。

public synchronized MyObj getData() {               
    synchronized (myLock) {
        synchronized (this) {
            if (isEmpty()) {                
                wait(0);                    
            }
        }       


        return getData();           
    }
}

public synchronized void addData(MyObj data) {
    if (!isFull()) {
        putData(data);
        synchronized (this) {
            notify();
        }
    }
}

在上面的代码中,如果第一个线程尝试获取数据并且队列为空,我会通过 wait(0) 进入等待状态,直到其他线程将数据添加到队列中,然后通过 notify() 释放等待状态。

现在我想在队列已满并且有人试图向其中添加更多数据时添加另一个“锁”:

public synchronized MyObj getData() {               
    synchronized (myLock) {
        synchronized (this) {
            if (isEmpty()) {                
                wait(0);                    
            }
        }       

        synchronized (this) {
            notify();
        }
        return getData();           
    }
}

public synchronized void addData(MyObj data) {
    synchronized (myLock) {
        synchronized (this) {
            if (isFull()) {
                wait(0);
            }
        }
    }

    synchronized (this) {
        notify();
        }
        PutData(data);
}

结果不是我所期望的,我猜我遇到了死锁,因为进程被卡住了。

更新

这是我获取数据的方式:

queueSize--;
startPointer = (startPointer + 1) % mqueueSize;
data = (String) queue[startPointer];

这是我添加数据的方式

  queueSize++;
  endPointer = (endPointer + 1) % mqueueSize;
  queue[endPointer] = data;

public synchronized boolean isEmpty() {
        return queueSize== 0;
    }

    public synchronized boolean isFull() {
        return queueSize== mqueueSize;
    }

最佳答案

为什么你有三个synchronized语句? wait(0) 只释放 this 上的锁,所以只保留那个锁并从方法和 中转储 synchronized同步(myLock)

每当您在某个对象上调用 wait(在本例中您正在调用 this)时,该对象上的锁将自动释放以允许其他线程继续进行。但是你永远不会在 myLock 上调用等待(你也不应该,因为你已经在调用 this 了)。那部分是多余的,会导致死锁。

考虑这种情况:应该添加的线程获取了 myLock 上的锁,但发现队列已满,因此它等待。此等待不会释放 myLock 上的锁。另一个线程想要取数据但是不能进入synchronized block ,因为第一个线程没有释放myLock上的锁。

结论:移除synchronized(myLock) block 。

关于java - 等待/通知死锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8519529/

相关文章:

java - 从sourceforge下载文件[即没有特定的文件名]

java - Android Eclipse LocalDate 无法解析为类型

java - java中静态变量的线程安全

java - 底部导航 View : Glitch that overwrites other layout

c++ - 使用多线程时程序变慢

c# - 为什么 Interlocked.Add() 方法必须返回一个值?

c# - 如何使用 C# 在运行时请求线程的锁和死锁?

c# - Windows Phone HttpClient PostAsync 挂起且无响应

php - 防止使用 SELECT...LOCK IN SHARE MODE 的 php 应用程序中的 mysql 死锁

java - Android Listview 文本对齐