[英]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 你的increaseRow
和increaseColumn
方法都应该有一个结构
lock.lock();
try {
// code including monitor.signal() here
} finally {
lock.unlock();
}
just as your sumRow
, sumColumn
and printMatrix
methods do. 就像你的sumRow
, sumColumn
和printMatrix
方法一样。 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.