'java async future and concurrency

in a service, we need to batch up calls to new relic logging. The below code is supposed to send asnc an array of messages when a limit is reached. However, we are losing messages. We don't care about the result (although it would be nice to log an error). In the below code, I would assume that when the monitor protected section is passed, a new caller of send could overwrite the eventArrayCopy in line 3? I think the developer struggled because the parameter sent to the async call could not be a simple (safe) local variable.

    @Override
    public CompletableFuture<HttpResponse<String>> send(JsonElement body)  {
    final JsonArray eventArrayCopy = new JsonArray();

    synchronized (monitor) {
        eventArray.add(body);
        log.info("added event to eventArray. array size:" + eventArray.size());
        if (eventArray.size() < senderConfig.getEventPerRequest() && !isTimeToSend()) 
     {
            return null;
        }
        eventArrayCopy.addAll(eventArray);
        eventArray = new JsonArray();
    }

    
    return CompletableFuture.supplyAsync(()->sendEvents(eventArrayCopy));
}

eventArray is gobal,but is only used inside the monitor.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source