【问题标题】:java synchronized on object vs synchronized on thisjava在对象上同步vs在此上同步
【发布时间】:2017-07-05 12:26:11
【问题描述】:

我想编写自己的简单信号量并按如下方式完成:

class Semaphore {
    private boolean done;
    private final Object lock = new Object();

    public Semaphore(boolean done){ this.done = done;}

    public void acquire() throws InterruptedException {
        synchronized (lock) {
            while (!done)
                lock.wait();

            done = false;
        }
    }

    public void release() {
        synchronized (lock) {
            done = true;
            lock.notify();
        }
    }
}

它工作正常。但是,如果我用同步(this)替换同步(锁定),它开始抛出 IllegalMonitorStateException。为什么会这样?

【问题讨论】:

  • lock.wait() 也应该更改为 this.wait()。所以 lock.notify().
  • @Alexei 是的,但我的问题是“为什么抛出这个异常”,而不是“如何做到这一点”

标签: java multithreading synchronize


【解决方案1】:

正如@Alexei Kaigorodov 在评论中提到的,当您将synchronized (lock) 替换为synchronize (this) 时。然后,您还需要将代码中的lock 替换为this。

this 表示当前对象与lock 对象不同。

现在,您将 synchronized (lock) 替换为 synchronize (this),这意味着您现在正试图获取当前对象的锁定,但您正在等待 Object 类的对象。

这绝对没问题:

public void acquire() throws InterruptedException {
    synchronized (this) {
        while (!done)
            this.wait();

        done = false;
    }
}

public void release() {
    synchronized (this) {
        done = true;
        this.notify();
    }
}

【讨论】:

  • 你说:“因为这表明当前对象不同于锁定对象。”是的,但是this 对象包含lock 对象,所以我想this 对象上的同步应该阻止我班级所有成员的所有操作。不是吗?
  • 我的意思是 this 上的同步应该在类的所有成员上同步工作,因为 this 代表整个对象并包括所有成员
  • 回答你的第一个问题。不,它们不一样。
  • @borune 在任何东西上同步不会阻塞任何操作,除了另一个线程的另一个同步。所有其他阻止只是协议,可以或不能在程序中实现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-29
  • 1970-01-01
  • 2011-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多