> From: "Dain Ironfoot" <[email protected]>
> To: "mechanical-sympathy" <[email protected]>
> Sent: Saturday, June 4, 2022 12:53:55 AM
> Subject: Compute in a lock free way
> Hello,
> I am writing a class to calculate average of prices. We use it to generate
> buy/sell signal for some financial instruments therefore latency is crucial.
> Prices are sent via different threads therefore class needs to be thread-safe.
> Am I correct in understanding that I have to use a lock to make the two
> operations (adding and incrementing) atomic? I have looked at
> AtomicLong/LongAdder/LongAccumulator but looks like they can only sum the
> numbers atomically.
> In other words, there is no way to do this in a lock-free manner?
you can group them in an object and do a CAS (see VarHandle.compareAndSet) on
the references
record Stat(BigDecimal sum, int count) { }
public final class Computer {
private volatile Stat stat;
public void add(double value) {
// do a CAS between stat and new Stat(BigDecimal.valueOf(value), stat.count +
1)
}
}
BTW in your example, rwLock, readLock and writeLock should be declared final to
avoid any publication issues,
see [
https://stackoverflow.com/questions/1621435/not-thread-safe-object-publishing |
https://stackoverflow.com/questions/1621435/not-thread-safe-object-publishing ]
regards,
Rémi
> Thank you!
> public final class Computer{
> private ReentrantReadWriteLock rwLock;
> private ReadLock readLock;
> private WriteLock writeLock;
> private BigDecimal sum;
> private int count;
> public AverageCalculatorThreadSafeImplementation2( ){
> this.rwLock = new ReentrantReadWriteLock();
> this.readLock = rwLock.readLock();
> this.writeLock = rwLock.writeLock();
> this.sum = new BigDecimal(0);
> }
> public final void add( double value ){
> writeLock.lock();
> try{
> sum = sum.add( BigDecimal. valueOf (value) );
> ++count;
> }finally{
> writeLock.unlock();
> }
> }
> public final double compute( ){
> readLock.lock();
> try{
> return sum.divide(BigDecimal. valueOf (count)).doubleValue();
> }finally{
> readLock.unlock();
> }
> }
> --
> You received this message because you are subscribed to the Google Groups
> "mechanical-sympathy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email
> to [ mailto:[email protected] |
> [email protected] ] .
> To view this discussion on the web, visit [
> https://groups.google.com/d/msgid/mechanical-sympathy/2d083587-2ee1-4f8f-a7ee-a99062a6ef5cn%40googlegroups.com?utm_medium=email&utm_source=footer
> |
> https://groups.google.com/d/msgid/mechanical-sympathy/2d083587-2ee1-4f8f-a7ee-a99062a6ef5cn%40googlegroups.com
> ] .
--
You received this message because you are subscribed to the Google Groups
"mechanical-sympathy" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web, visit
https://groups.google.com/d/msgid/mechanical-sympathy/145240008.2007500.1654332340634.JavaMail.zimbra%40u-pem.fr.