Functional way to implement a thread safe shared counter

不羁岁月 提交于 2019-12-03 15:28:12

Is this thread safe by any chance?

No, unless you have already created the immutable object in a synchronized block, this is not thread-safe. There are chances of creating a corrupt immutable object under thread race condition.

And to achieve the same functionality you can use AtomicInteger which avoids explicit synchronization.

public class Servlet extends HttpServlet {

  public AtomicInteger incrementer = new AtomicInteger (0);

  @Override
  public void service(ServletRequest req, ServletResponse res) throws ... {
    int newValue = incrementer.incrementAndGet();
    super.service(req, res);
  }
}

Thread safety from immutables looks much more like this.

val x = AtomicReference(Vector("salmon", "cod"))

// Thread 1
val y = x.get
println(y(y.length-1))

// Thread 2
x.getAndSet(x.get.tail)

If you were working mutably, you would be sorely tempted to have Thread 2 alter a mutable list, which could then make Thread 1's index fail. Or you'd have to copy the data, which might be very expensive if you didn't have collections meant to reuse as much as practical (and if the vector was longer). Or you'd have to synchronize large blocks in both threads instead of just atomically getting and/or get-setting your data.

You still have to synchronize somehow, and you may have to deal with out-of-date copies of data. But you don't have to keep track of who has a copy of which data structure and synchronize everyone like mad because that data might change out from under you and throw exceptions all over the place.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!