同步数组列表中的竞争条件

时间:2018-12-26 12:07:42

标签: java thread-synchronization mapdb

我正在将对象列表的处理包含在一个同步块中,但是最终处于竞争状态。我是错误地使用了同步块,还是我的代码还有其他问题?该列表实际上是使用mapdb实例化的。

private static List<MessageHolder> msgHolders;
//messageSequenceDB instantiation
msgHolders = (List<MessageHolder>) messageSequenceDB.indexTreeList("tempStorage", Serializer.JAVA).createOrOpen();


synchronized (msgHolders) {
        System.out.println(Thread.currentThread().getName() +"->"+msgHolders.toString());
        for (MessageHolder holder : msgHolders) {
            if(holder.getStatus().equalsIgnoreCase(STATUS_INITIAL) {
                holder.setStatus(STATUS_DISPATCHED);
                LOGGER.info("MESSAGE SEQUENCER: Message {} dispatched", holder);
                //Remaining code
}}}

我期望一个对象只能由一个线程处理。如果第二个线程试图分派它,则状态条件应该失败。但是我得到了输出,因为所有线程都处理很少的消息。

在此处提供示例输出。

pool-12-thread-1->[MessageHolder [key=TradeId.1, message=1, status=Initial], MessageHolder [key=TradeId.2, message=222, status=Initial]]

pool-12-thread-2->[MessageHolder [key=TradeId.2, message=222, status=Initial], MessageHolder [key=TradeId.1, message=1111, status=Initial]]

pool-12-thread-3->[MessageHolder [key=TradeId.2, message=222, status=Initial]]

pool-12-thread-1->[MessageHolder [key=TradeId.1, message=11, status=Initial]]

ID 222的消息被所有3个线程处理。我该怎么做才能确保同步?

1 个答案:

答案 0 :(得分:0)

我已经通过将字段状态设置为可变来解决了这个问题。