2016-02-24 59 views
-1

我开始阅读Java和我在多线程主题。另外我是C程序员,所以我对C语言的线程有所了解。多线程锁定和通知

我在寻找线程如何在特定对象上相互通信。

我发现这个问题Java: How can the wait() and notify() methods be called on Objects that are not threads?但我有冲突。

我知道​​关键字适用锁定机制的概念。因此,如果我同步了一个对象,然后在此对象上调用wait,是否意味着该锁将被释放以供另一个线程访问?正如前面链接的例子

+1

等待将解锁,并把该线程在列表中等待通知 –

+1

等待/通知是最古老和多线程最低级别的API之一。它几乎不再使用。我建议你在过去的11年中使用新增的并发API。我将从Java 8 Streams开始并向后工作。 –

回答

3

你说你很熟悉线程C.

您可以通过想象隐式的p_thread_mutex_t变量和与每个Java对象关联的隐式变量来理解Java的行为。

假设我们有一些对象,foo。我们使用m(foo)来表示想象中的互斥体,并让我们使用c(foo)来表示想像的条件变量。

一个synchronized(foo) { ... }块锁几乎是一样的:

pthread_mutex_lock(m(foo)); 
... 
pthread_mutex_unlock(m(foo)); 

唯一不同的是,Java的保证是没有办法脱身synchronized块的未解锁的互斥。即使...引发异常,互斥锁仍将被解锁。

所以,回答你的问题:

foo.wait()调用基本上转化为pthread_cond_wait(c(foo), m(foo));

1

的一般规则如下:

  • 线程只能叫wait()notify()当它获得锁​​

  • 两个线程不能在运行代码​​同时阻止。其他线程必须等待获取该锁。

  • 如果获取锁的线程调用wait(),它会自动释放锁。当它已被notify()编辑时,它会尝试再次自动获取锁定。

2

当等待()被调用,同步对象的锁将被释放。请参阅Oracle文档中的以下摘录。 “监视器”这个词的意思是相同的“锁定”

“ 公共最终空隙等待() 抛出InterruptedException的 造成当前线程等待,直到其他线程调用notify()方法或用于notifyAll的()方法这个对象,换句话说,这个方法的行为就好像它只是执行调用wait(0)一样 当前线程必须拥有这个对象的监视器。在该对象的监视器上通过调用notify方法或notifyAll方法来唤醒该线程然后等待,直到它可以重新获得监视器的所有权并恢复执行。

如在一个参数的版本,中断和杂散唤醒是可能的,而且这种方法应该总是在一个循环中使用:

synchronized (obj) { 
    while (<condition does not hold>) 
     obj.wait(); 
    ... // Perform action appropriate to condition 
} 

此方法应该仅由一个线程是的所有者被称为这个对象的监视器。有关线程可以成为监视器所有者的方式的说明,请参阅notify方法。

+0

Re,_​​the “监视器”这个词的含义与“锁定”相同_:是的,现在我想它是这样,但是当Java发明时,“监视器”应该唤起CAR Hoare的监视器https://en.wikipedia.org/ wiki/Monitor_%28synchronization%29从这个意义上说,监视器应该是一个_object_,它有一个关联的互斥锁和一个或多个条件变量,并且该对象的每个method_都应该在互斥锁上同步。 –