我有一个在 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 控制并发管理并且必须确保完成同步。
添加回答
举报
0/150
提交
取消