java.lang.Error: Maximum lock count exceeded
·
在学习某马进阶视频的时候发现,其中Java程序模拟多线程同时卖票,使用三种锁方法运行时均发现票卖完后,程序不能自己结束,过了一会给出错误:超过最大锁计数。
注:修改方法在下方代码下面红色加粗字体

Exception in thread "Thread-2" java.lang.Error: Maximum lock count exceeded
at java.base/java.util.concurrent.locks.ReentrantLock$Sync.nonfairTryAcquire(ReentrantLock.java:138)
at java.base/java.util.concurrent.locks.ReentrantLock$NonfairSync.tryAcquire(ReentrantLock.java:199)
at java.base/java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1225)
at java.base/java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:267)
at com.itheima.demo09.Lock.RunnableImpl.run(RunnableImpl.java:33)
at java.base/java.lang.Thread.run(Thread.java:844)
考虑是因为没有释放锁。造成请求次数过多倍的大于获取请求次数。
即The problem is you release your semaphore more times than acquired.
下面是源代码
public class RunnableImpl implements Runnable {
//定义一个多个线程共享的票源
private int ticket = 100;
//1.在成员位置创建一个ReentrantLock对象
Lock l = new ReentrantLock();
//设置线程任务:卖票
@Override
public void run() {
//使用死循环,让卖票操作重复执行
while (true) {
//2.在可能会出现安全问题的代码前调用Lock接口中的方法lock获取锁
l.lock();
//先判断票是否存在
if (ticket > 0) {
//提高安全问题出现的概率,让程序睡眠
try {
Thread.sleep(10);
//票存在,卖票 ticket--
System.out.println(Thread.currentThread().getName() + "-->正在卖第" + ticket + "张票");
ticket--;
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//3.在可能会出现安全问题的代码后调用Lock接口中的方法unlock释放锁
l.unlock();//无论程序是否异常,都会把锁释放
}
}
}
}
}
发现如果在售卖最后一张票的时候先获取到 l 锁,if判断语句不成立,则没有解锁语句unlock被执行,while死循环也不会停止,即程序一直在循环,但是拿到锁之后一直没有拿到解锁语句,导致Error;该Error在源码中有说明。将代码中添加else语句并在其中添加一个unlock解锁和break跳出死循环,修改如下(第22行代码中体现修改):
public class RunnableImpl implements Runnable {
private int ticket = 100;
final Lock l = new ReentrantLock();
int i=0;
@Override
public void run() {
while (i<150) {
l.lock();
if (ticket > 0) {
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName() + "出票号:" + ticket);
ticket--;
i++;
System.out.println(l);
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
l.unlock();
System.out.println(l);
}
} else {
l.unlock();
break;
}
}
}
}
中间部分输出语句是为了观察锁有没有被释放。运行结果如下:

解锁并break之后程序可以自己跳出死循环!
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)