> From: "Dain Ironfoot" <vicvanda...@gmail.com> > To: "mechanical-sympathy" <mechanical-sympathy@googlegroups.com> > 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:mechanical-sympathy+unsubscr...@googlegroups.com | > mechanical-sympathy+unsubscr...@googlegroups.com ] . > 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 mechanical-sympathy+unsubscr...@googlegroups.com. To view this discussion on the web, visit https://groups.google.com/d/msgid/mechanical-sympathy/145240008.2007500.1654332340634.JavaMail.zimbra%40u-pem.fr.