我开始阅读Java和我在多线程主题中的应用。我也是一名C程序员,所以我对C语言的线程知识。
我正在寻找线程如何在特定对象上相互通信。
我发现了这个问题Java: How can the wait() and notify() methods be called on Objects that are not threads?,但我发生了冲突。
我知道synchronized
关键字适用于锁定机制的概念。因此,如果我同步一个对象然后在此对象上调用wait
这是否意味着将释放锁以供另一个线程访问?如上一个链接中的示例
答案 0 :(得分:3)
你说你熟悉C中的线程。
您可以通过想象隐式p_thread_mutex_t
变量和与每个Java对象关联的隐式pthread_cond_t
变量来理解Java的行为。
假设我们有一些对象 foo 。让我们使用 m(foo)来表示想象的互斥锁,让我们使用 c(foo)来表示想象的条件变量。
synchronized(foo) { ... }
块锁几乎与此相同:
pthread_mutex_lock(m(foo));
...
pthread_mutex_unlock(m(foo));
唯一的区别是,Java保证在不解锁互斥锁的情况下无法退出同步块。即使...
抛出异常,互斥锁仍然会被解锁。
所以,问题的答案是:
对foo.wait()
的来电基本上转换为pthread_cond_wait(c(foo), m(foo));
答案 1 :(得分:2)
调用wait()时,将释放同步对象上的锁定。请参阅以下Oracle文档摘录。 “监视器”一词的含义与“锁定”相同
” public final void wait() 抛出InterruptedException 导致当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法。换句话说,此方法的行为就像它只是执行调用wait(0)一样。 当前线程必须拥有此对象的监视器。 线程释放此监视器的所有权并等待,直到另一个线程通过调用notify方法或notifyAll方法通知等待此对象监视器的线程唤醒。然后该线程等待,直到它可以重新获得监视器的所有权并继续执行。
在一个参数版本中,中断和虚假唤醒是可能的,并且此方法应始终在循环中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
此方法只能由作为此对象监视器所有者的线程调用。有关线程可以成为监视器所有者的方式的说明,请参阅notify方法。
“
答案 2 :(得分:1)
一般规则如下:
线程只有在获得锁wait()
notify()
或synchronized
两个线程无法同时在synchronized
块内运行代码。其他线程必须等待获取锁。
如果线程获取名为wait()
的锁,则会自动释放锁。当它notify()
时,它会尝试再次自动获取锁定。
答案 3 :(得分:-1)
看一下cubyhole“生产者/消费者”的例子,它可以帮助
http://www.tutorialspoint.com/javaexamples/thread_procon.htm