java多线程下,unlock报java.lang.Illega
2022-05-23 本文已影响0人
hongzhenw
测试代码
若在代码里使用的是tryLock和unlock
private Lock mLock = new ReentrantLock();
public void demo() {
for (int i = 0; i < 10; i++) {
final int finalI = i;
new Thread(new Runnable() {
@Override
public void run() {
test(finalI);
}
}).start();
}
}
public void test(int index) {
try {
if (!mLock.tryLock()) {
System.err.println(index + " locked:" + Thread.currentThread().getName());
return;
}
// 伪代码 开始
System.err.println(index + " run code");
// 伪代码 结束
} catch (Exception e) {
e.printStackTrace();
} finally {
mLock.unlock();
System.err.println(index + " unlock:" + Thread.currentThread().getName());
}
}
多线程下,以上代码会报以下错误信息:
java.lang.IllegalMonitorStateException
at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:156)
at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1291)
at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:466)
解决方案1
把tryLock方法放在try代码块外,理由:若获取不到锁,则会return,不再执行finally里的unlcok(测试代码则会,因为try代码块执行了)
修复代码如下:
public void test(int index) {
if (!mLock.tryLock()) {
System.err.println(index + " locked:" + Thread.currentThread().getName());
return;
}
try {
// 伪代码 开始
System.err.println(index + " run code");
// 伪代码 结束
} catch (Exception e) {
e.printStackTrace();
} finally {
mLock.unlock();
System.err.println(index + " unlock:" + Thread.currentThread().getName());
}
}
输出结果如下:
0 run code
0 unlock:Thread-3
1 run code
1 unlock:Thread-4
2 locked:Thread-5
3 locked:Thread-6
4 locked:Thread-7
5 locked:Thread-8
6 locked:Thread-9
7 locked:Thread-10
8 locked:Thread-11
9 locked:Thread-12
解决方案2
把Lock改为ReentrantLock,以及配合isHeldByCurrentThread方法
修复代码如下:
public void test(int index) {
try {
if (!mLock.tryLock()) {
System.err.println(index + " locked:" + Thread.currentThread().getName());
return;
}
// 伪代码 开始
System.err.println(index + " run code");
// 伪代码 结束
} catch (Exception e) {
e.printStackTrace();
} finally {
if (mLock.isHeldByCurrentThread()) {
mLock.unlock();
System.err.println(index + " unlock:" + Thread.currentThread().getName());
}
}
}
输出结果如下:
0 run code
0 unlock:Thread-3
1 locked:Thread-4
2 locked:Thread-5
3 locked:Thread-6
4 locked:Thread-7
5 locked:Thread-8
6 locked:Thread-9
7 locked:Thread-10
8 locked:Thread-11
9 locked:Thread-12