0

そこで、次の出力を出力するプログラムを作成しようとしています。

44
33
22
11

プログラムはマルチスレッドであると想定されており、競合状態を防ぐためにロックを使用する必要があります。また、スレッドが出力したい番号が変数 threadnum (出力する必要がある次の番号) と一致しない場合に待機する必要があるように、Condition を使用する必要があります。実行しようとすると 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){

静的変数をスレッドのインデックスと比較しています。静的変数は (すべてのスレッドがセットアップされた後) 同じ値になるため、1 つの同じスレッドに対してしか while ループを呼び出していません。他のすべては単にブロックされています。そして、これを行うため:

lock.lock();

while ループの外側では、唯一の実行中のスレッドが最初に正しく実行されるだけです (つまり、ロックされたとき)。ループの他のすべての繰り返しでは、有効なロックがありません。

finally{
    lock.unlock();
}

不正なモニター状態の例外が発生します。

于 2013-03-11T10:01:04.697 に答える
1

ループlock.lock();内に移動する必要があります。while

ただし、同期ブロック内でロックが必要な理由がまったくわかりません...特に、各スレッドが異なるロック/条件を使用しているため、プログラムが必要なことを実行する可能性はほとんどありません。あなたはおそらくlock静的にするつもりでしたか?

于 2013-03-11T10:04:00.027 に答える