IllegalMonitorStateException异常

笔者在kafka重复消费exception一文中处理offset重复提交的问题后,在执行了一段时间后发现又出现了重复消费的问题,于是检查了生产日志,发现没有了CommitFailedException问题,于是根据重复消费的id具体查看,发现了一个异常,同步锁解锁异常,这个异常的抛出是因为当前线程释放了一个它并没有持有的锁,这种操作是非法的。

此次重复消费的问题大概就找出原因了,代码中出现了异常后往外抛出去了,kafka在消费的时候,认为消息没有正常消费,于是就让消费者再次消费,但是消费还是失败,就这样一直循环下去,导致消息消费越来越慢。

在检查代码的过程中,发现了同步锁释放锁的时候失去了锁对象,因为同步锁设置了过期时间,由于接口逻辑执行时间过长,锁已经失效了,在unlock的时候,锁不存在了,就报错了,于是修改同步锁释放锁资源的逻辑:在释放锁的时候判断当前前锁是否存在,并且查询当前线程是否保持此锁定。

示例:

if(lock.lock() && lock.isHeldByCurrentThread()) {
}

lock.lock()

在Java中,ReentrantLock是一个可重入的互斥锁,它与synchronized关键字类似,可以用来实现多线程间的互斥访问,防止数据竞争和线程安全问题。在使用ReentrantLock时,我们需要使用lock()方法来获取锁,以确保在执行临界区代码时,只有一个线程可以访问。

lock.lock()方法是ReentrantLock类中获取锁的方法,调用该方法会尝试获取锁。如果锁当前没有被其他线程持有,则获取锁并返回。如果锁已经被其他线程持有,则当前线程会被阻塞,直到获取锁为止。同时,如果当前线程在等待锁的过程中被中断,那么lock.lock()方法会抛出InterruptedException异常。

下面是一个简单的示例代码,展示了如何使用lock.lock()方法获取锁:

public class LockDemo {
    private ReentrantLock lock = new ReentrantLock();

    public void doSomething() {
        lock.lock(); // 获取锁
        try {
            // 执行临界区代码
            System.out.println(Thread.currentThread().getName() + " is running");
        } finally {
            lock.unlock(); // 释放锁
        }
    }
}

lock.isHeldByCurrentThread()

lock.isHeldByCurrentThread()是ReentrantLock类中的一个方法,用于判断当前线程是否持有锁。如果当前线程持有锁,则返回true;否则返回false。可以使用lock.isHeldByCurrentThread()方法来判断当前线程是否持有锁,从而避免出现不必要的错误。

下面是一个示例代码,展示了如何使用lock.isHeldByCurrentThread()方法判断当前线程是否持有锁:

public class LockDemo {
    private ReentrantLock lock = new ReentrantLock();

    public void doSomething() {
        lock.lock(); // 获取锁
        try {
            // 判断当前线程是否持有锁
            if (lock.isHeldByCurrentThread()) {
                // 执行业务代码 ...
                System.out.println(Thread.currentThread().getName() + " is running");
            }
        } finally {
            lock.unlock(); // 释放锁
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是三叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值