KafkaConsumer is not safe for multi-threaded access

问题背景:
1.使用ScheduledExecutorService创建一个线程池
2.创建多个kafkaConsumer对象,用来接收不同主题的消息
3.使用线程池来操作不同的kafkaConsumer对象


问题原因:
KafkaConsumer是非线程安全的类,当使用多个线程操作同一个KafkaConsumer对象时就会引起这个错误。


分析:
假设现在有两个kafkaConsumer对象ka和kb;ScheduledExecutorService创建了一个线程池,里面包含2个线程T1和T2
然后把ka和kb接收消息的任务提交给线程池,让他周期性的执行这两个任务。
如果在任务里加入了线程对象相关的调试信息,会发现T1/T2与ka/kb的对应关系不是固定的,例如下面这样:
第一次:T1执行ka,T2执行kb
第二次:T1执行kb,T2执行ka


这就造成了:T1,T2这两个线程都对同一个对象ka进行了操作,虽然并不是同时执行的,但是对于kafka这个消息系统来说,偶发性的,他会发现有两个线程对相同的kafkaConsumer对象进行了操作,于是就发生了KafkaConsumer is not safe for multi-threaded access


解决办法:
1.线程与KafkaConsumer对象的对应关系是1:1
2.要保证线程与KafkaConsumer对象的关系是固定不变的,也就是说,一个线程始终都只能操作同一个KafkaConsumer对象且一个KafkaConsumer对象始终是由同一个线程来操作的。


注意:上面的解决办法就决定了,不能使用ScheduledExecutorService这个线程池来操作KafkaConsumer。因为线程池本来是为了共享而存在的,他在执行任务时,线程与任务的关系是不固定的,而KafkaConsumer要求的是固定的线程
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值