所以我正在尝试编写一个打印出以下输出的程序:
44
33
22
11
该程序应该是多线程的,必须使用锁以防止竞争条件。它还必须使用Condition,这样当一个线程想要打印的数字与变量threadnum(必须打印的下一个数字)不对应时,它必须等待。我已经掌握了大部分内容,除非我在尝试运行它时遇到IllegalMonitorStateExceptions,我不确定是什么导致它,也不知道如何解决它。我将不胜感激。提前谢谢。
public class Threadlocksrev implements Runnable {
Lock lock = new ReentrantLock();
Condition wrongNumber = lock.newCondition();
int i;
static int threadnum = 4;
public Threadlocksrev(int i){
this.i = i;
}
private int getI(){
return i;
}
@Override
public synchronized void run() {
lock.lock();
while(true){
if (threadnum == i){
try{
System.out.print(getI());
System.out.print(getI());
System.out.print("\n");
threadnum--;
wrongNumber.signalAll();
}
catch(Exception e){
e.printStackTrace();
}
finally{
lock.unlock();
}
}
else{
try {
wrongNumber.await();
}
catch (InterruptedException e) {
e.printStackTrace();
}
finally{
wrongNumber.signalAll();
lock.unlock();
}
}
}
}
}
主要班级:
public class ThreadlocksrevInit {
private static final int max_threads = 4;
public static void main(String[] args) {
Threadlocksrev task1 = new Threadlocksrev(1);
Threadlocksrev task2 = new Threadlocksrev(2);
Threadlocksrev task3 = new Threadlocksrev(3);
Threadlocksrev task4 = new Threadlocksrev(4);
Thread thread1 = new Thread(task1);
Thread thread2 = new Thread(task2);
Thread thread3 = new Thread(task3);
Thread thread4 = new Thread(task4);
thread1.start();
thread2.start();
thread3.start();
thread4.start();
}
}
答案 0 :(得分:3)
你正忙着在同一个线程中旋转,试图一遍又一遍地解锁,当调用线程不拥有锁时会导致你的非法监视器状态异常。在这段代码中:
if (threadnum == i){
您正在将静态变量与线程的索引进行比较。因为静态变量将是相同的值(在设置所有线程之后),您只是为同一个线程调用while循环。所有其他人都被阻止了。因为你这样做:
lock.lock();
在while循环的外部 中,唯一运行的线程仅在第一次正确执行时(即具有锁定时)。在循环的所有其他迭代中,它没有有效的锁,因此当它调用时:
finally{
lock.unlock();
}
您的非法监视器状态异常。
答案 1 :(得分:1)
您需要在lock.lock();
循环中移动while
。
但是,我不确定为什么你需要在同步块内部锁定...特别是,你的每个线程都使用不同的锁/条件,所以程序不太可能做你需要的。你可能想让lock
静态吗?