Skip to content

org.apache.rocketmq.common.stats.StatsItemSet#getAndCreateStatsItem has multi-thread problem #515

@xiangwangcheng

Description

@xiangwangcheng

The code below

    public StatsItem getAndCreateStatsItem(final String statsKey) {
        StatsItem statsItem = this.statsItemTable.get(statsKey);
        if (null == statsItem) {
            statsItem = new StatsItem(this.statsName, statsKey, this.scheduledExecutorService, this.log);
            StatsItem prev = this.statsItemTable.put(statsKey, statsItem);

            if (null != prev) {

                // statsItem.init();
            }
        }

        return statsItem;
    }

has multi-thread problem. Because we can not ensure the atomicity of

StatsItem statsItem = this.statsItemTable.get(statsKey);
StatsItem prev = this.statsItemTable.put(statsKey, statsItem);

Here is the test case. The result is not always the correct one 20000.

public class BrokerStatsManagerTest {

    private BrokerStatsManager brokerStatsManager;
    private ThreadPoolExecutor executor;
    @Before
    public void init() {
        brokerStatsManager = new BrokerStatsManager("DefaultCluster");
        executor = new ThreadPoolExecutor(100, 200, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000), new ThreadFactoryImpl("testMultiThread"));
    }

    @Test
    public void testBrokerStatsManager() throws InterruptedException {

        for(int i =0; i < 10000; i++) {
            executor.submit(new Runnable() {
                @Override
                public void run() {
                    brokerStatsManager.incTopicPutNums("topicTest", 2, 1);
                }
            });
        }
        Thread.sleep(5000);
        System.out.println(brokerStatsManager.getStatsItem(TOPIC_PUT_NUMS,"topicTest").getValue());
    }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions