在多线程中锁定和解锁 java
lock and unlock in multi thread java
我在我的代码中使用锁定和解锁并启动一些客户和生产者线程。
第 lock.waite 行抛出 IllegalMonitorStateException.Why?
有了锁,在一个Thread中不提供使用这个列表的条件?
static class Customeer extends Thread {
private List<String> list;
private Lock lock;
public Customeer(List<String> list, Lock lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
if (list.size() == 0) {
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.remove(0);
lock.unlock();
}
}
static class Producer extends Thread {
private List<String> list;
private Lock lock;
public Producer(List<String> list, Lock lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
list.add("hello");
list.notify();
lock.unlock();
}
}
您的代码存在一些问题,即:
list.wait();
除非在同步方法(或块代码)中,否则无法获取列表的监视器。
list.notify();
,除非在同步方法(r 块代码)中,否则无法释放列表的监视器。
您不能使用 none 同步方法或部分中的 .wait()
或 .notify()
。
像该片段一样更改您的代码:
static class Customeer extends Thread {
private List<String> list;
private Lock lock;
public Customeer(List<String> list, Lock lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
if (list.size() != 0) {
list.remove(0);
}
lock.unlock();
}
}
static class Producer extends Thread {
private List<String> list;
private Lock lock;
public Producer(List<String> list, Lock lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
list.add("hello");
lock.unlock();
}
}
这些字符串正在调用 IllegalMonitorStateException
。
line lock.wait
throws IllegalMonitorStateException
. Why?
其实并没有这条线
然而,有一行调用list.wait()
。 那 是你的问题的原因。
为了在对象上调用 wait()
,您必须首先持有该对象的原始互斥锁。您只能使用 synchronized
获得 那种 类型的锁。 (synchronized
方法或 synchronized
块。)
你的情况:
- 您正在
List
实例上调用 wait
。
- 您正在锁定
Lock
个实例。
- 您为
Object.wait
持有错误的锁。您持有的是 Lock
锁,而不是原始互斥锁。
所以...如果您想在 Lock
实例上执行相当于等待和通知的操作,那么您需要做的就是调用 Lock.newCondition()
来获取 Condition
目的。然后你像这样使用它:
private final Lock lock = ...
private final Condition cond = lock.newCondition();
try {
lock.acquire();
while (!the_condition_we_are_waiting_for) {
cond.await();
}
// do stuff
} finally {
lock.release();
}
作为参考,如果您重写上面的代码以使用原始互斥体,它看起来会像这样。
private final Object lock = new Object();
synchronized(lock) {
while (!the_condition_we_are_waiting_for) {
lock.wait();
}
// do stuff
}
(您可以使用 any 对象作为锁,但最好使用隐藏的对象,并且不会被任何其他代码锁定。 )
总而言之,要么使用带有 synchronized
、Object.wait
和 Object.notify*
的原始互斥锁,要么使用带有 Lock.acquire
、[=32= 的 Lock
]、Condition.await
和 Condition.signal
。不要试图混合使用这两种锁定和条件变量。
我在我的代码中使用锁定和解锁并启动一些客户和生产者线程。 第 lock.waite 行抛出 IllegalMonitorStateException.Why? 有了锁,在一个Thread中不提供使用这个列表的条件?
static class Customeer extends Thread {
private List<String> list;
private Lock lock;
public Customeer(List<String> list, Lock lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
if (list.size() == 0) {
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.remove(0);
lock.unlock();
}
}
static class Producer extends Thread {
private List<String> list;
private Lock lock;
public Producer(List<String> list, Lock lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
list.add("hello");
list.notify();
lock.unlock();
}
}
您的代码存在一些问题,即:
list.wait();
除非在同步方法(或块代码)中,否则无法获取列表的监视器。list.notify();
,除非在同步方法(r 块代码)中,否则无法释放列表的监视器。
您不能使用 none 同步方法或部分中的 .wait()
或 .notify()
。
像该片段一样更改您的代码:
static class Customeer extends Thread {
private List<String> list;
private Lock lock;
public Customeer(List<String> list, Lock lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
if (list.size() != 0) {
list.remove(0);
}
lock.unlock();
}
}
static class Producer extends Thread {
private List<String> list;
private Lock lock;
public Producer(List<String> list, Lock lock) {
this.list = list;
this.lock = lock;
}
@Override
public void run() {
lock.lock();
list.add("hello");
lock.unlock();
}
}
这些字符串正在调用 IllegalMonitorStateException
。
line
lock.wait
throwsIllegalMonitorStateException
. Why?
其实并没有这条线
然而,有一行调用list.wait()
。 那 是你的问题的原因。
为了在对象上调用 wait()
,您必须首先持有该对象的原始互斥锁。您只能使用 synchronized
获得 那种 类型的锁。 (synchronized
方法或 synchronized
块。)
你的情况:
- 您正在
List
实例上调用wait
。 - 您正在锁定
Lock
个实例。 - 您为
Object.wait
持有错误的锁。您持有的是Lock
锁,而不是原始互斥锁。
所以...如果您想在 Lock
实例上执行相当于等待和通知的操作,那么您需要做的就是调用 Lock.newCondition()
来获取 Condition
目的。然后你像这样使用它:
private final Lock lock = ...
private final Condition cond = lock.newCondition();
try {
lock.acquire();
while (!the_condition_we_are_waiting_for) {
cond.await();
}
// do stuff
} finally {
lock.release();
}
作为参考,如果您重写上面的代码以使用原始互斥体,它看起来会像这样。
private final Object lock = new Object();
synchronized(lock) {
while (!the_condition_we_are_waiting_for) {
lock.wait();
}
// do stuff
}
(您可以使用 any 对象作为锁,但最好使用隐藏的对象,并且不会被任何其他代码锁定。 )
总而言之,要么使用带有 synchronized
、Object.wait
和 Object.notify*
的原始互斥锁,要么使用带有 Lock.acquire
、[=32= 的 Lock
]、Condition.await
和 Condition.signal
。不要试图混合使用这两种锁定和条件变量。