IllegalMonitorStateException异常

这篇博客讨论了一个由于在并发编程中未正确使用锁导致的`IllegalMonitorStateException`异常。错误代码中,`channelRead`和`call`方法在读写时没有进行同步控制,从而引发问题。修正后的代码通过加入`synchronized`关键字确保了线程安全,避免了读写操作的混乱。博客强调了在多线程环境下正确使用锁的重要性,以保证数据一致性。
摘要由CSDN通过智能技术生成

java.lang.IllegalMonitorStateException

异常信息以及异常代码
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
	at com.sun.proxy.$Proxy0.sendMessage(Unknown Source)
	at com.king.ZkClient.main(ZkClient.java:17)
Caused by: java.util.concurrent.ExecutionException: java.lang.IllegalMonitorStateException
	at java.base/java.util.concurrent.FutureTask.report(FutureTask.java:122)
	at java.base/java.util.concurrent.FutureTask.get(FutureTask.java:191)
	at com.king.InitServiceClient$2.invoke(InitServiceClient.java:66)
	... 2 more
Caused by: java.lang.IllegalMonitorStateException
	at java.base/java.lang.Object.wait(Native Method)
	at java.base/java.lang.Object.wait(Object.java:328)
	at com.king.UserServiceHandler.call(UserServiceHandler.java:39)
	at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.lang.Thread.run(Thread.java:834)
526, 2021 12:09:18 上午 io.netty.channel.DefaultChannelPipeline onUnhandledInboundException
警告: An exceptionCaught() event was fired, and it reached at the tail of the pipeline. It usually means the last handler in the pipeline did not handle the exception.
java.lang.IllegalMonitorStateException
	at java.base/java.lang.Object.notify(Native Method)
	at com.king.UserServiceHandler.channelRead(UserServiceHandler.java:33)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340)
	at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1359)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362)
	at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348)
	at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:935)
	at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:134)
	at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580)
	at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497)
	at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459)
	at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:858)
	at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
	at java.base/java.lang.Thread.run(Thread.java:834)


该异常主要是因为没有加锁导致,错误代码如下

 @Override
    //读取服务端数据时执行
    public  void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        result = msg.toString();
        //读取到服务端数据后唤醒,否则继续等待客户端写入到服务端这个操作
        notify();
    }

    @Override
    public  Object call() throws Exception {
        context.writeAndFlush(param);
        wait();
        return result;
    }

在读写的时候因为没有锁而控制不了先后顺序,导致读线程并没有唤醒写线程。

修正代码

加了关键字之后,一方加锁等待,另一方加锁读取,使数据一致。

 @Override
    //读取服务端数据时执行
    public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        result = msg.toString();
        //读取到服务端数据后唤醒,否则继续等待客户端写入到服务端这个操作
        notify();
    }

    @Override
    public synchronized Object call() throws Exception {
        context.writeAndFlush(param);
        wait();
        return result;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值