我正在研究多线程程序。线程在矩阵 (workerThread) 中工作,我有一个打印矩阵状态的线程(显示)。我收到此异常,在行监视器的 Matrix 类的 increaseRow() 中.signal()
谁能告诉我,这是怎么回事?
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();
}
}
显示类:
public class Display extends Thread {
private Matrix matrix;
public Display(Matrix matrix) {
this.matrix = matrix;
}
@Override
public void run() {
while(true)
matrix.printMatrix();
}
}
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));
}
}
}
更新
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
最佳答案
是的,问题是在 increaseRow
中,您调用 monitor.signal()
时没有先锁定 lock
。来自 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. Implementations must document this precondition and any actions taken if the lock is not held. Typically, an exception such as
IllegalMonitorStateException
will be thrown.
increaseRow
和 increaseColumn
方法都应该有一个结构
lock.lock();
try {
// code including monitor.signal() here
} finally {
lock.unlock();
}
就像您的 sumRow
、sumColumn
和 printMatrix
方法一样。或者,您可能希望为每一行和每一列设置一个单独的监视器(和条件)。您基本上需要考虑所有并发限制 - 如果您不了解您要实现的目标,就很难提供更多指导。
关于调用 signal() 时抛出 java.lang.IllegalMonitorStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26384304/