0

所以我正在尝试编写一个打印出以下输出的程序:

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();
    }

}
4

2 回答 2

3

您正忙于在同一个线程中旋转,一遍又一遍地尝试解锁,当调用线程不拥有锁时,这会导致您的非法监视器状态异常。在这段代码中:

if (threadnum == i){

您正在将静态变量与线程的索引进行比较。因为静态变量将是相同的值(在设置所有线程之后),所以您只为一个相同的线程调用 while 循环。所有其他人都被阻止了。因为你这样做:

lock.lock();

在 while 循环之外,唯一运行的线程仅在第一次正确执行(也就是当它有锁时)。在循环的所有其他迭代中,它没有有效的锁,所以当它调用时:

finally{
    lock.unlock();
}

你得到你的非法监视器状态异常。

于 2013-03-11T10:01:04.697 回答
1

您需要lock.lock();while循环内移动。

但是,我不确定为什么您根本需要在同步块中使用锁...特别是,您的每个线程都使用不同的锁/条件,因此程序不太可能执行您需要的操作。你可能打算制作lock静态?

于 2013-03-11T10:04:00.027 回答