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

Java 同步数组列表中的竞争条件,java,thread-synchronization,mapdb,Java,Thread Synchronization,Mapdb,我将对象列表的处理封装在一个同步块中,但最终处于竞争状态。我是否错误地使用了synchronized块,或者我的代码是否存在其他问题?该列表实际上是用mapdb实例化的 private static List<MessageHolder> msgHolders; //messageSequenceDB instantiation msgHolders = (List<MessageHolder>) messageSequenceDB.indexTreeList("temp

我将对象列表的处理封装在一个同步块中,但最终处于竞争状态。我是否错误地使用了synchronized块,或者我的代码是否存在其他问题?该列表实际上是用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
}}}

ID为222的消息由所有3个线程处理。如何确保同步?

我已通过将字段状态设置为不稳定状态来解决此问题。

如何初始化
msgHolders
并不重要;在首先查询锁的线程完成其工作之前,任何人都不能进入同步块。很奇怪,剩下的代码是什么?您是否在任何地方重新初始化
msgHolders
?是否确定
messageSequenceDB.indexTreeList(..)
返回相同的对象?我的意思是对象id(如
@6ef123
)对于所有线程都是相同的?或者您是否尝试创建单例对象
private static final object LOCKER=new object()并将其放入同步块?请发布由多个线程执行的整个方法。我怀疑每个线程都有自己的
magholder
列表,所以
synchronized
块实际上不能按预期工作。@Ivan是的,你是对的。我的嫌疑犯也一样。每个线程都有单独的msgHolder。输出结果证实了这一点。方法是完整的。“剩余代码”部分仅包含对另一个具有status modified holder对象的方法的调用。
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]]