Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Thread-safe implementation of max

Tags:

I need to implement global object collecting statistics for web server. I have Statistics singleton, which has method addSample(long sample), which subsequently call updateMax. This has to be obviously thread-safe. I have this method for updating maximum of whole Statistics:

AtomicLong max;  private void updateMax(long sample) {     while (true) {         long curMax = max.get();         if (curMax < sample) {             boolean result = max.compareAndSet(curMax, sample);             if (result) break;         } else {             break;         }     } } 

Is this implementation correct? I am using java.util.concurrent, because I believe it would be faster than simple synchronized. Is there some other / better way to implement this?

like image 225
Tibor Blenessy Avatar asked May 20 '11 12:05

Tibor Blenessy


People also ask

What are thread-safe methods?

A data type or static method is threadsafe if it behaves correctly when used from multiple threads, regardless of how those threads are executed, and without demanding additional coordination from the calling code.

What are the methods to make collection thread-safe?

A thread-safe variant of ArrayList in which all mutative operations (e.g., add, set, remove..) are implemented by creating a separate copy of an underlying array. It achieves thread safety by creating a separate copy of the List which is different than vector or other collections used to provide thread-safety.

Which set is thread-safe?

The collection classes that are thread-safe in Java are Stack, Vector, Properties, Hashtable, etc.

How do you make increment thread-safe?

In order to be thread safe you must declare the variable as follows: public static volatile int value; Now value being volatile, will be accessed in a synchronized block. Making the variable volatile is different from accessing it from a synchronized block.


1 Answers

As of Java 8, LongAccumulator has been introduced. It is advised as

This class is usually preferable to AtomicLong when multiple threads update a common value that is used for purposes such as collecting statistics, not for fine-grained synchronization control. Under low update contention, the two classes have similar characteristics. But under high contention, expected throughput of this class is significantly higher, at the expense of higher space consumption.

You can use it as follows:

LongAccumulator maxId = new LongAccumulator(Long::max, 0); //replace 0 with desired initial value maxId.accumulate(newValue); //from each thread 
like image 78
lorenzop Avatar answered Sep 22 '22 15:09

lorenzop