No, this does not guarantee thread safety. Even if incrementAndGet()
itself atomic, getting the value from the Properties
object and setting it back is not.
Consider the following scenario:
- Topic # 1 gets the value from the
Properties
object. For argument, let's say that this is "100". - Thread # 2 gets the value from the
Properties
object. Since nothing happened, this value is still "100". - Thread # 1 creates an
AtomicInteger
, increments it, and places "101" in the Properties
object. - Thread # 2 does the same and puts "101" in the
Properties
object instead of the 102 you expected.
EDIT:
In a more productive note, the best approach would be to simply save AtomicInteger
on your state map and increase it in place. Thus, you have one copy and you do not need to worry about racing, as described above. Since the Properties
class extends Hashtable<Object, Object>
, this should technically work, although Properties
not really intended for values ββthat are not String
s, and you would be much better off with a modern thread-safe Map
, like ConcurrentHashMap
:
public void tSafe(List<Foo> list, ConcurrentMap<String, AtomicInteger> status) { if(list == null) { return; } String key = "COUNT"; status.putIfAbsent(key, new AtomicInteger(0)); list.parallelStream() .filter(Foo::check) .forEach(foo -> { status.get(ket).incrementAndGet(); }); }
source share