为了账号安全,请及时绑定邮箱和手机立即绑定

使用阻塞队列的对象池在死锁中运行

使用阻塞队列的对象池在死锁中运行

largeQ 2021-09-03 13:23:00
我有一个在 payara 5 中运行的 Java 应用程序。我需要汇集一些我的 bean 将使用的引擎对象(来自库)。创建引擎需要在单独的线程中完成。因此我想出了我的 EnginePool 和我的 EngineProducer。这个想法是 EnginePool 管理两个 BlockingQueues。一个用于可用引擎,另一个用于被 bean 使用并需要再次变为可用的引擎。EnginePool 应该只可用一次,所以它是一个单例。@Singleton@Startup@LocalBean@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)public class AbbyyEnginePool implements OcrEnginePool<IEngine> {private static final Logger logger = LoggerFactory.getLogger(AbbyyEnginePool.class);@Resource(lookup = "java:comp/DefaultManagedThreadFactory")private ManagedThreadFactory threadFactory;private static final int DEFAULT_ENGINE_COUNT = 3;private BlockingQueue<EngineMetaInfo> availableEngines = new ArrayBlockingQueue<>(DEFAULT_ENGINE_COUNT);private BlockingQueue<IEngine> enginesToRelease = new ArrayBlockingQueue<>(DEFAULT_ENGINE_COUNT);private Map<IEngine, IEngine> proxiesMapping = new ConcurrentHashMap<>(DEFAULT_ENGINE_COUNT);private int poolSize;public AbbyyEnginePool() {    this(DEFAULT_ENGINE_COUNT);}public AbbyyEnginePool(int poolSize) {    this.poolSize = poolSize;    availableEngines = new ArrayBlockingQueue<>(poolSize);    enginesToRelease = new ArrayBlockingQueue<>(poolSize);    proxiesMapping = new ConcurrentHashMap<>(poolSize);}void setThreadFactory(ManagedThreadFactory threadFactory) {    this.threadFactory = threadFactory;}@PostConstructvoid init() {    EngineProducer engineProducer = new EngineProducer(availableEngines, enginesToRelease, poolSize);           Thread engineProducerThread = threadFactory.newThread(engineProducer);    engineProducerThread.setName("engineProducer");    engineProducerThread.start();}
查看完整描述

1 回答

?
一只甜甜圈

TA贡献1836条经验 获得超5个赞

问题是容器管理所有并发。在单例的情况下,这意味着对字段的所有访问都将获得写锁。

解决方案是使用@ConcurrencyManagement(BEAN) 注解。这意味着 bean 控制并发管理并且必须确保完成同步。


查看完整回答
反对 回复 2021-09-03
  • 1 回答
  • 0 关注
  • 195 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信