gpt4 book ai didi

Java 嵌套监视器(摆脱明显的死锁)

转载 作者:行者123 更新时间:2023-11-30 05:24:42 25 4
gpt4 key购买 nike

我正在同一个对象上进行同步和阻塞。每个线程都调用 PuppetShow 类中的 testQueue() 方法,该方法为每个要阻塞的线程实例化一个不同的对象。我的问题是,一旦容量==0,遇到该条件的第一个线程会在其对象上调用 wait() ,然后程序挂起并且没有其他线程运行。第三个线程根据 println 语句输出“waaah”,然后不执行其他行,尽管我在这之后实例化了线程。

如何越过 PuppetShow() 类中 testQueue 方法中的 lock.wait() 行?

我希望能够阻止不同的对象并将它们添加到 vector 中,以便对线程组进行排队。这就是为什么我要阻止不同的对象,然后将它们添加到 vector 中。为了通知线程,我只需通知 vector 中某个位置的元素即可。

import java.util.Vector;

public class PuppetShow {

private int numSeats = 2;
private int capacity = numSeats;
private Vector<Object> attendingPuppetShow = new Vector<Object>();
public Vector<Object> waitingStudents = new Vector<Object>();

public void testQueue() {
Object lock = new Object();
System.out.println("testQueue begin");
synchronized(lock) {
if(testAttending(lock)) {
try {
System.out.println("waaah");
lock.wait();
System.out.println("ugh");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}

public synchronized boolean testAttending(Object lock) {
System.out.println("testAttending");
boolean status;
if(capacity==0) {
waitingStudents.add(lock);
System.out.println("capacity="+capacity+" ws size="+waitingStudents.size());
status = true;
}
else {
capacity--;
attendingPuppetShow.add(lock);
System.out.println("capacity="+capacity+" aPS size="+attendingPuppetShow.size());
status = false;
}
return status;
}

public synchronized void testRelease() {
if(waitingStudents.size() > 0) {
while(waitingStudents.size() > 0) {
synchronized(waitingStudents.elementAt(0)) {
waitingStudents.elementAt(0).notify();
}
waitingStudents.removeElementAt(0);
capacity++;
}
}
}
}

class GreenStudent extends Thread {

private PuppetShow ps = new PuppetShow();

public GreenStudent(int id, PuppetShow ps) {
setName("GreenStudent-" + id);
this.ps = ps;
}

@Override
public void run() {
System.out.println(getName()+" queuing for show");
ps.testQueue();
}
}

class StaffMember extends Thread {

private PuppetShow ps = new PuppetShow();

public StaffMember(int id, PuppetShow ps) {
setName("StaffMember-" + id);
this.ps = ps;
}

@Override
public void run() {
ps.testRelease();

}
}

class Driver {

public static void main(String[] args) {
// TODO Auto-generated method stub

PuppetShow ps = new PuppetShow();
GreenStudent gs1 = new GreenStudent(1, ps);
GreenStudent gs2 = new GreenStudent(2, ps);
GreenStudent gs3 = new GreenStudent(3, ps);

StaffMember sm = new StaffMember(1,ps);

gs1.run();
gs2.run();
gs3.run();
sm.run();
}
}

最佳答案

         gs1.run();
gs2.run();
gs3.run();
sm.run();

需要

         gs1.start();
gs2.start();
gs3.start();
sm.start();

在您的示例中,run 将由调用线程(主线程)调用。 start 将启动另一个线程,然后最终调用 run

关于Java 嵌套监视器(摆脱明显的死锁),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58894361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com