简体   繁体   English

调用signal()时抛出java.lang.IllegalMonitorStateException

[英]java.lang.IllegalMonitorStateException trhown when calling signal()

i' m working in a multithreading program. 我正在从事多线程计划。 The threads are working in a matrix (workerThread) and i have got a thread (display) that print the matrix state.i' m getting this exception, inside the increaseRow() of Matrix class at the line monitor.signal() 线程在矩阵(workerThread)中工作,我有一个线程(显示)打印矩阵状态。我在行monitor.ignal()的Matrix类的increaseRow()内得到此异常

can someone tell me, what's wrong? 谁能告诉我,有什么不对?

public class Matrix {

    private int row;
    private int column;

    private int[][] matrix;
    private Map<Integer, String> mapForRow;
    private Map<Integer, String> mapForColumn;

    private Lock lock;
    private Condition condition;
    private Condition monitor;

    private boolean rowIncreased;
    private boolean columnIncreased;
    private boolean columnCanBeAdded;
    private boolean rowCanBeAdded;
    private boolean print;

    public Matrix(int row, int column) {
        this.matrix = new int[row][column];
        lock = new ReentrantLock();
        mapForColumn = new LinkedHashMap<Integer, String>();
        mapForRow = new LinkedHashMap<Integer, String>();
        condition = lock.newCondition();
        monitor = lock.newCondition();
        rowIncreased = false;
        columnIncreased = false;
        rowCanBeAdded = false;
        columnCanBeAdded = false;
        print = false;
    }

    public void increaseRow(int row) {
        if (!mapForRow.containsKey(row))
            mapForRow.put(row, "not increased");
        if (mapForRow.get(row).equals("not increased") && !columnIncreased) {
            mapForRow.get(row).equals("increased");
            rowIncreased = true;
            for (int j = 0; j < matrix.length; j++)
                setMatrix(row, j, matrix[row][j] + 1);
            mapForRow.put(row, "not increased");
            rowIncreased = false;
            print = true;
            monitor.signal();
        }
    }

    public void increaseColumn(int column) {
        if (!mapForColumn.containsKey(column))
            mapForColumn.put(column, "not increased");
        if (mapForColumn.get(column).equals("not increased") && !rowIncreased) {
            mapForColumn.get(column).equals("increased");
            columnIncreased = true;
            for (int i = 0; i < matrix.length; i++)
                setMatrix(i, column, matrix[i][column] + 1);
            mapForColumn.put(column, "not increased");
            columnIncreased = false;
            print = true;
            monitor.signal();
        }
    }

    public int sumColumn(int column) {
        lock.lock();
        int sum = 0;
        try {
            columnCanBeAdded = false;
            while (columnIncreased || rowIncreased || rowCanBeAdded) {
                condition.await();
            }
            for (int i = 0; i < matrix.length; i++)
                sum += matrix[i][column];
            columnCanBeAdded = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        condition.signalAll();
        print = true;
        monitor.signal();
        return sum;
    }

    public int sumRow(int row) {
        lock.lock();
        int sum = 0;
        try {
            rowCanBeAdded = false;
            while (columnIncreased || rowIncreased || columnCanBeAdded) {
                condition.await();
            }
            for (int j = 0; j < matrix.length; j++)
                sum += matrix[row][j];
            rowCanBeAdded = true;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        condition.signalAll();
        print = true;
        monitor.signal();
        return sum;
    }

    public void printMatrix() {
        lock.lock();
        try {
            while (!print) {
                monitor.await();
            }
            System.out.println("begin print matrix");
            for (int i = 0; i < row; i++) {
                System.out.println();
                for (int j = 0; j < column; j++)
                    System.out.print(matrix[i][j]);
            }
            System.out.println("end print matrix");
            print = false;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }

    public void setMatrix(int row, int column, int number) {
        matrix[row][column] = number;
    }

    public static void main(String[] args) {
        Matrix matrix = new Matrix(10, 10);
        for (int i = 0; i < 10; i++)
            for (int j = 0; j < 10; j++)
                matrix.setMatrix(i, j, 0);
        for (int i = 0; i < 10; i++) {
            WorkerThread workerThread = new WorkerThread(matrix);
            workerThread.start();
        }
        // print the matrix state
        Display display = new Display(matrix);
        display.start();

    }
}

the display class: 显示类:

    public class Display extends Thread {

        private Matrix matrix;

        public Display(Matrix matrix) {
            this.matrix = matrix;
        }

        @Override
        public void run() {
            while(true)
            matrix.printMatrix();
        }

    }

the workerThread class: workerThread类:

public class WorkerThread extends Thread {

    private Matrix matrix;

    public WorkerThread(Matrix matrix) {
        this.matrix = matrix;
    }

    @Override
    public void run() {
        // prevent thread to die
        while (true) {
            matrix.increaseColumn(new Random().nextInt(9));
            matrix.increaseRow(new Random().nextInt(9));
            try {
                sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            matrix.sumRow(new Random().nextInt(9));
            matrix.sumColumn(new Random().nextInt(9));
        }
    }

}

UPDATE UPDATE

Exception in thread "Thread-7" Exception in thread "Thread-6" Exception in thread "Thread-4" Exception in thread "Thread-1" Exception in thread "Thread-5" Exception in thread "Thread-9" Exception in thread "Thread-0" Exception in thread "Thread-2" Exception in thread "Thread-3" Exception in thread "Thread-8" java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signal(AbstractQueuedSynchronizer.java:1941)
    at Matrix.increaseColumn(Matrix.java:67)
    at WorkerThread.run(WorkerThread.java:15)
java.lang.IllegalMonitorStateException
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.signal(AbstractQueuedSynchronizer.java:1941)
    at Matrix.increaseColumn(Matrix.java:67)
    at WorkerThread.run(WorkerThread.java:15)begin print matrix
end print matrix

Yes, the problem is that in increaseRow you're calling monitor.signal() without having locked lock first. 是的,问题是,在increaseRow你打电话monitor.signal()而无需锁定lock第一。 From the documentation for Condition.signal() : Condition.signal()的文档:

An implementation may (and typically does) require that the current thread hold the lock associated with this Condition when this method is called. 当调用此方法时,实现可能(并且通常确实)要求当前线程保持与此Condition关联的锁。 Implementations must document this precondition and any actions taken if the lock is not held. 实现必须记录此前提条件以及未保持锁定时所采取的任何操作。 Typically, an exception such as IllegalMonitorStateException will be thrown. 通常,将抛出异常,例如IllegalMonitorStateException

Both your increaseRow and increaseColumn methods should have a structure of 你的increaseRowincreaseColumn方法都应该有一个结构

lock.lock();
try {
    // code including monitor.signal() here
} finally {
    lock.unlock();
}

just as your sumRow , sumColumn and printMatrix methods do. 就像你的sumRowsumColumnprintMatrix方法一样。 Alternatively, you may want to have a separate monitor (and conditions) for each row and for each column. 或者,您可能希望为每行和每列分别设置一个监视器(和条件)。 You basically need to consider all your concurrency constraints - it's hard to give more guidance without more idea of what you're trying to achieve. 您基本上需要考虑所有并发约束 - 如果不了解您想要实现的目标,很难提供更多指导。

In methods increaseRow(int) and increaseColumn(int) you need to have a lock held on lock , otherwise you cannot call the monitor.signal() 在方法increaseRow(int)increaseColumn(int)你需要锁定一个lock ,否则你不能调用monitor.signal()

lock.lock();
try {
     ....
     monitor.signal();
} finally {
    lock.unlock();
}

From the docs for signal 来自文件的信号

An implementation may (and typically does) require that the current thread hold the lock associated with this Condition when this method is called. 当调用此方法时,实现可能(并且通常确实)要求当前线程保持与此Condition关联的锁。

and then for ReentrantLock : 然后是ReentrantLock

If this lock is not held when any of the Condition waiting or signalling methods are called, then an IllegalMonitorStateException is thrown. 如果在调用任何条件等待或信令方法时未保持此锁定,则抛出IllegalMonitorStateException。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 线程通信:如何发出信号,表明已单击某个键? java.lang.IllegalMonitorStateException - Thread communication: How to signal that a key was clicked? java.lang.IllegalMonitorStateException 超时时发生java.lang.IllegalMonitorStateException - java.lang.IllegalMonitorStateException on timeout 从同步块中调用wait时发生java.lang.IllegalMonitorStateException - java.lang.IllegalMonitorStateException whilst calling wait from synchronized block java.lang.IllegalMonitorStateException (java selenium) - java.lang.IllegalMonitorStateException (java selenium) 通知异常 java.lang.IllegalMonitorStateException Locks - Notify exception java.lang.IllegalMonitorStateException Locks notifyAll()方法上的java.lang.IllegalMonitorStateException - java.lang.IllegalMonitorStateException on notifyAll() method 线程“main”java.lang.IllegalMonitorStateException中的异常 - Exception in thread “main” java.lang.IllegalMonitorStateException 我的代码抛出java.lang.IllegalMonitorStateException - my code throws java.lang.IllegalMonitorStateException 导致java.lang.IllegalMonitorStateException的原因 - What causes an java.lang.IllegalMonitorStateException 当我以静态方式同步块调用wait()时,为什么Java会抛出java.lang.IllegalMonitorStateException? - Why Java throw java.lang.IllegalMonitorStateException when I invoke wait() in static way synchronized block?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM