多线程java中的锁定和解锁
我在我的代码中使用lock和unlock,并启动一些客户和生产商线程。 line lock.waite抛出非法监视器状态异常。为什么? 有了锁,在一个线程中不提供使用此列表的条件多线程java中的锁定和解锁,java,multithreading,locking,Java,Multithreading,Locking,我在我的代码中使用lock和unlock,并启动一些客户和生产商线程。 line lock.waite抛出非法监视器状态异常。为什么? 有了锁,在一个线程中不提供使用此列表的条件 static class Customeer extends Thread { private List<String> list; private Lock lock; public Customeer(List<String
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();
}
}
静态类Customeer扩展线程{
私人名单;
私家锁;
公共客户(列表、锁定){
this.list=列表;
this.lock=锁;
}
@凌驾
public void run(){
lock.lock();
if(list.size()==0){
试一试{
list.wait();
}捕捉(中断异常e){
e、 printStackTrace();
}
}
列表。删除(0);
lock.unlock();
}
}
静态类生成器扩展线程{
私人名单;
私家锁;
公共制作人(列表、锁定){
this.list=列表;
this.lock=锁;
}
@凌驾
公开募捐{
lock.lock();
添加(“你好”);
list.notify();
lock.unlock();
}
}
您的代码有一些问题,即:
list.wait()代码>除非处于同步方法(或块代码)内,否则无法获取列表的监视器
list.notify()代码>,除非处于同步方法(r块代码)内,否则无法释放列表的监视器
.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();
}
}
静态类Customeer扩展线程{
私人名单;
私家锁;
公共客户(列表、锁定){
this.list=列表;
this.lock=锁;
}
@凌驾
public void run(){
lock.lock();
如果(list.size()!=0){
列表。删除(0);
}
lock.unlock();
}
}
静态类生成器扩展线程{
私人名单;
私家锁;
公共制作人(列表、锁定){
this.list=列表;
this.lock=锁;
}
@凌驾
公开募捐{
lock.lock();
添加(“你好”);
lock.unlock();
}
}
这些字符串正在调用IllegalMonitorStateException
行lock.wait
抛出IllegalMonitorStateException
。为什么?
事实上,没有这样的界线
但是,有一行调用list.wait()
。那就是你的问题的原因
要在对象上调用wait()
,必须首先持有该对象上的基本互斥锁。您只能使用synchronized
获得这种锁。(一个synchronized
方法或一个synchronized
块。)
就你而言:
- 您正在调用
实例上的列表
等待
- 您正在锁定
实例Lock
- 您持有的
对象的锁类型不正确。请稍候。您持有的是
锁,而不是原始互斥锁锁
锁
实例上执行与等待和通知等效的操作,则需要执行的操作是调用锁.newCondition()
以获取条件
对象。然后你就这样使用它:
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
}
(可以使用任何对象作为锁,但最好使用隐藏的对象,并且不会被任何其他代码锁定。)
总之,可以将基本互斥锁与
同步
,对象一起使用。等待
和对象。通知*
,或者将锁与锁一起使用。获取
,锁。释放
,条件。等待
和条件。信号
。不要尝试混合使用两种类型的锁定和条件变量。您的意思是锁定的工作方式与同步块不同吗?