Java对象监视器

Java对象监视器,java,multithreading,Java,Multithreading,我读到: Object sync = new Object(); /* inter to monitor */ try { sync.wait(); } catch (InterruptedException ex) { } finally { } /* our code*/ /* exit from monotir */ sync.notify(); 就像 synchronize (sync) { /* our code*/ } 这是真的吗 我在我的代码中尝试了这个

我读到:

Object sync = new Object();

/* inter to monitor */
try {
    sync.wait();
} catch (InterruptedException ex) {

} finally {

}

/* our code*/
/* exit from monotir */
sync.notify();
就像

synchronize (sync) {
    /* our code*/
}
这是真的吗

我在我的代码中尝试了这个,但它不起作用

private Object data;
    private Object sync = new Object();

    public static void main(String[] args) {
        SimpleProducerConsumer pc = new SimpleProducerConsumer();
        new Thread(pc.new Producer()).start();
        new Thread(pc.new Consumer()).start();
    }

    public Object pop() {
        try {
            sync.wait();
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        System.out.println("Before");
        Object d = data;
        data = null;
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("pop");
        System.out.println("After");
        sync.notify();
        return d;
    }

    public void push(Object d) {
        try {
            sync.wait();
        } catch (InterruptedException e1) {
            e1.printStackTrace();
        }
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        data = d;
        System.out.println("push");
        sync.notify();
    }

    class Producer implements Runnable {
        @Override
        public void run() {
            while (true) {
                push(new Object());
            }
        }
    }

    class Consumer implements Runnable {
        @Override
        public void run() {
            while (true) {
                pop();
            }
        }
    }
我的代码怎么了?

不,
sync.wait()
sync.notify()
sychronize(sync){…
..}
远非同义词

事实上,为了调用
wait
,您必须处于
synchronized
块中

我将解释
synchronize
wait
notify
的概念,它们之间的区别将很清楚

  • 当一个线程进入一个
    synchronized(sync){…}
    块时,它会抓住
    sync
    监视器的锁(这意味着该锁被占用,并且没有其他线程可以在该点进入该块)

  • 当线程调用
    sync.wait()
    时,它会临时释放
    sync
    的锁。(它正在等待某些事情发生。某些需要锁才能发生的事情。)

  • 一个线程调用
    sync.notify()
    ,通知其他线程发生了什么事情,此时它们将恢复执行

我的代码有什么问题

例如,我假设您希望确保如果两个线程尝试弹出某个内容,那么它们应该避免执行以下操作:

Thread 1              Thread 2
--------------------------------------
Object d = data;
                      Object d = data;
                      data = null;
data = null;
return d;
                      return d;
为了避免这种情况,您需要确保
d=data
data=null
以原子方式进行

这可以通过以下方式实现

Object d;
synchronized (sync) {
    d = data;
    data = null;
}
synchronized (sync) {
    while (d == null)
        sync.wait();
}
(现在,上面线程1中的第一条和第二条语句无法拆分。)

此外,您似乎希望
pop
被阻塞,也就是说,如果
d==null
它应该等待其他线程来
推送
某些内容

这可以通过以下方式实现

Object d;
synchronized (sync) {
    d = data;
    data = null;
}
synchronized (sync) {
    while (d == null)
        sync.wait();
}
并在
push
中执行
sync.notify()

相关问题/进一步阅读:

  • 我在这里的回答给出了一个示例,说明在生产者/消费者的情况下,如果允许在同步块外调用
    等待
    通知
    ,会发生什么

  • 否,
    sync.wait()
    sync.notify()
    sychronize(sync){…
    ..}
    远非同义词

    事实上,为了调用
    wait
    ,您必须处于
    synchronized
    块中

    我将解释
    synchronize
    wait
    notify
    的概念,它们之间的区别将很清楚

    • 当一个线程进入一个
      synchronized(sync){…}
      块时,它会抓住
      sync
      监视器的锁(这意味着该锁被占用,并且没有其他线程可以在该点进入该块)

    • 当线程调用
      sync.wait()
      时,它会临时释放
      sync
      的锁。(它正在等待某些事情发生。某些需要锁才能发生的事情。)

    • 一个线程调用
      sync.notify()
      ,通知其他线程发生了什么事情,此时它们将恢复执行

    我的代码有什么问题

    例如,我假设您希望确保如果两个线程尝试弹出某个内容,那么它们应该避免执行以下操作:

    Thread 1              Thread 2
    --------------------------------------
    Object d = data;
                          Object d = data;
                          data = null;
    data = null;
    return d;
                          return d;
    
    为了避免这种情况,您需要确保
    d=data
    data=null
    以原子方式进行

    这可以通过以下方式实现

    Object d;
    synchronized (sync) {
        d = data;
        data = null;
    }
    
    synchronized (sync) {
        while (d == null)
            sync.wait();
    }
    
    (现在,上面线程1中的第一条和第二条语句无法拆分。)

    此外,您似乎希望
    pop
    被阻塞,也就是说,如果
    d==null
    它应该等待其他线程来
    推送
    某些内容

    这可以通过以下方式实现

    Object d;
    synchronized (sync) {
        d = data;
        data = null;
    }
    
    synchronized (sync) {
        while (d == null)
            sync.wait();
    }
    
    并在
    push
    中执行
    sync.notify()

    相关问题/进一步阅读:

    • 我在这里的回答给出了一个示例,说明在生产者/消费者的情况下,如果允许在同步块外调用
      等待
      通知
      ,会发生什么


    您的
    push()
    pop()
    方法都在同一个锁对象上等待
    notify()
    ,但是没有人在该对象上调用
    notify()
    notifyAll()
    ,因此它们在无限期地等待。 这里发生的是:

  • 制作人在
    sync.wait()
    内部调用
    push()
    等待有人调用
    sync.notify()
  • 消费者在
    sync.wait()
  • 死锁

  • 您的
    push()
    pop()
    方法都在同一个锁对象上等待
    notify()
    ,但是没有人在该对象上调用
    notify()
    notifyAll()
    ,因此它们无限期地等待。 这里发生的是:

  • 制作人在
    sync.wait()
    内部调用
    push()
    等待有人调用
    sync.notify()
  • 消费者在
    sync.wait()
  • 死锁

  • 不,他们完全不同。如果要暂停执行直到满足某些条件,可以从
    synchronized
    块内部调用
    wait()
    。一旦满足该条件,您就可以在同一对象上使用
    notify()
    notifyAll()
    (同样在
    同步的
    块中)

    因此,在这种情况下,两个线程实际上可以同时在同一对象上的
    synchronized
    块中;当一个o