Atomic Boolean vs SynchronizedBoolean in Java - java

I've come across these two in some multi-threaded code and was wondering if there is if/any difference between the two.
I mean does the use of an AtomicBoolean, rather than a SynchronizedBoolean, make a
significant difference in performance?
And does it affect the correctness of the computation?

AtomicBoolean is a part of the standard java concurrent package. SynchronizedBoolean is part of a set of utilities created by Doug Lea (author of much of the java concurrent packages). Performance-wise, you should expect AtomicBoolean to perform better -- it uses a volatile boolean whereas SynchronizedBoolean uses a ReadWriteLock.
However in practice for most applications you won't notice much difference.
The real difference (and what should guide your choice) is in the semantics the two classes offer. AtomicBoolean provides just simple set/get/compareAndSet operations. The SynchronizedBoolean offers atomic boolean operations and exposes its internal lock to allow you to execute Runnables within the context of its value.
Doug Lea has offered this source free to the community. I have found an extension to SynchronizedBoolean, WaitableBoolean particularly useful since it allows you to execute a Runnable within the lock whenever a particular state change occurs.

Related

Are java Lock implementations using synchronized code? [duplicate]

Is there a difference between 'ReentrantLock' and 'synchronized' on how it's implemented on CPU level?
Or do they use the same 'CAS' approach?
If we are talking about ReentrantLock vs synchronized (also known as "intrinsic lock") then it's a good idea to look at Lock documentation:
All Lock implementations must enforce the same memory synchronization semantics as provided by the built-in monitor lock:
A successful lock operation acts like a successful monitorEnter
action
A successful unlock operation acts like a successful monitorExit
action
So in general consider that synchronized is just an easy-to-use and concise approach of locking. You can achieve exactly the same synchronization effects by writing code with ReentrantLock with a bit more code (but it offers more options and flexibility).
Some time ago ReentrantLock was way faster under certain conditions (high contention for example), but now Java uses different optimizations techniques (like lock coarsening and adaptive locking) to make performance differences in many typical scenarios barely visible to the programmer.
There was also done a great job to optimize intrinsic lock in low-contention cases (e.g. biased locking). Authors of Java platform do like synchronized keyword and intrinsic-locking approach, they want programmers do not fear to use this handy tool (and prevent possible bugs). That's why synchronized optimizations and "synchronization is slow" myth busting was such a big deal for Sun and Oracle.
"CPU-part" of the question:
synchronized uses a locking mechanism that is built into the JVM and MONITORENTER / MONITOREXIT bytecode instructions. So the underlying implementation is JVM-specific (that is why it is called intrinsic lock) and AFAIK usually (subject to change) uses a pretty conservative strategy: once lock is "inflated" after threads collision on lock acquiring, synchronized begin to use OS-based locking ("fat locking") instead of fast CAS ("thin locking") and do not "like" to use CAS again soon (even if contention is gone).
ReentrantLock implementation is based on AbstractQueuedSynchronizer and coded in pure Java (uses CAS instructions and thread descheduling which was introduced it Java 5), so it is more stable across platforms, offers more flexibility and tries to use fast CAS appoach for acquiring a lock every time (and OS-level locking if failed).
So, the main difference between these locks implementations in terms of performance is a lock acquiring strategy (which may not exist in specific JVM implementation or situation).
And there is no general answer which locking is better + it is a subject to change during the time and platforms. You should look at the specific problem and its nature to pick the most suitable solution (as usually in Java)
PS: you're pretty curious and I highly recommend you to look at HotSpot sources to go deeper (and to find out exact implementations for specific platform version). It may really help. Starting point is somewhere here: http://hg.openjdk.java.net/jdk8/jdk8/hotspot/file/87ee5ee27509/src/share/vm/runtime/synchronizer.cpp
The ReentrantLock class, which implements Lock, has the same concurrency and memory semantics as synchronized, but also adds features like lock polling, timed lock waits, and interruptible lock waits. Additionally, it offers far better performance under heavy contention.
Source
Above answer is extract from Brian Goetz's article. You should read entire article. It helped me to understand differences in both.

Java uses synchronisation... What does Haskell use?

So I am pretty new to Haskell and would like to know, if synchronisation is used to prevent corruption when multithreading Java, how is this done in Haskell? I've only found useless or overly complicated responses on google.
Your question is a bit ambiguous since one may use multithreading for either concurrency or parallelism, which are distinct problems with distinct solutions.
In both cases, you'll need to make sure your programs are compiled with SMP support and ran using multiple RTS threads: see the GHC manual's section about concurrency.
Concurrency
As others have pointed out, synchronization will be a non problem in the vast majority of your code, since you'll mostly be dealing with pure functions. This is true in any language if you keep mutable state and libraries that rely on it under armed guard religiously avoid mutable state unless it is properly wrapped behind a pure API. Concurrency is an area where Haskell shines because its semantics require purity. Types are used to describe impure operations instead, making it dead easy to spot code where some sort of synchronization might be needed.
Typically, your application's state will be backed by a transactional database which will handle synchronization and persistence for you. You will not need any additional synchronization at all if your concurrent application does not have additional state.
In other cases, haskell has a handy Software Transactional Memory implementation. It allows you to write and compose code written in an imperative-looking style, without explicit locking, while having atomicity and guarantees against deadlocks. It is the foolproof(tm) way to write concurrent code.
Lastly, there are some low-level primitives available in base: plain old mutable references with IORef, semaphores, and MVars which can be used as if they were variables protected by a mutex.
There also are channels in base, but beware: they are unbounded !
Parallelism
This is also an area where Haskell shines because of its non-strict semantics. Non-strictness allows you to write code that expresses your logic in a straightforward manner while not getting committed to a specific evaluation order.
As a consequence, you can describe a parallel evaluation strategy separately from the business logic. Writing parallel code is then just a matter of placing the right annotation in the right spot.
Here is an example that was/is used in production at Bdellium:
map outputParticipant parts `using` parListChunk 10 rdeepseq
^^^^^ business logic ^^^^^^ ^^^^ eval. strategy ^^^^
The code can be understood as follows: Parallel workers will fully evaluate the results of mapping the outputParticipant function to individual items in the parts list, distributing the work in chunks of 10 elements.
This answer will pertain to functional languages in general - no synchronisation are needed. As functions in functional programming have no side effects: functions accept a value and return a value, there's no mutable state. Such functions are inherently thread safe.

Volatile vs Atomic in Java, why do we need atomic toolkit

Volatile eliminates visibility and ordering issues. While atomic toolkit provides atomicity of operations.
Volatile uses happens-before relation and Atomic uses compare and swap.
Why there is a need to introduce new layer of abstraction like atomic toolkit, instead of enhancing volatile keyword itself? Is there any specific cases which may be solved by atomic toolkit?
Actually if you'll take closer look into Atomic* implemetations then you'll see that all of them holds volatile field with value.
IMHO atomics is already an extension of volatile mechanism which provides convenient way to do atomic CAS operations.
Also there is a benefits of hiding CAS implementation. For example hotspot jvm heavily uses intrinsics to achieve to squeeze performance.
Changing an existing language construct like volatile would most likely mean that you break existing applications. So this is typically not an option, in particular not for the Java language. Creating a new library does not effect existing applications and is thus completely backwards compatible.
In addition to that, the classes in the atomicpackage offer advanced operations like compareAndSet that you cannot just add to the volatile keyword.

synchronized vs ReentrantLock vs AtomicInteger execution time

I can see that ReentrantLock is around 50% faster than synchronized and AtomicInteger 100% faster. Why such difference with the execution time of these three synchronization methods: synchronized blocks, ReentrantLock and AtomicInteger (or whatever class from the Atomic package).
Are there any other popular and extended synchronizing methods aside than these ones?
A number of factor effect this.
the version of Java. Java 5.0 was much faster for ReentrantLock, Java 7 not so much
the level of contention. synchronized works best (as does locking in general) with low contention rates. ReentrantLock works better with higher contention rates. YMWV
how much optimisation can the JIT do. The JIT optimise synchronized in ways ReentrantLOck is not. If this is not possible you won't see the advantage.
synchronized is GC free in it's actions. ReentrantLock can create garbage which can make it slower and trigger GCs depending on how it is used.
AtomicInteger uses the same primitives that locking uses but does a busy wait. CompareAndSet also called CompareAndSwap i.e. it is much simpler in what it does (and much more limited as well)
The ConcurrentXxxx, CopyOnWriteArrayXxxx collections are very popular. These provide concurrency without needing to use lock directly (and in some cases no locks at all)
AtomicInteger is much faster than the other two synchronization methods on your hardware because it is lock-free. On architectures where the CPU provides basic facilities for lock-free concurrency, AtomicInteger's operations are performed entirely in hardware, with the critical usually taking a single CPU instruction. In contrast, ReentrantLock and synchronized use multiple instructions to perform their task, so you see some considerable overhead associated with them.
I think that you are doing a common mistake evaluating those 3 elements for comparison.
Basically when a ReentrantLock is something that allows you more flexibility when your are synchronizing blocks compared with the synchronized key. Atomic is something that adopts a different approach based on CAS(Compare and Swap) to manage the updates in a concurrent context.
I suggest you to read in deep a bible of concurrency for the Java platform.
Java Concurrency in Practice - Brian Göetz, Tim Peierls, Joshua Bloch, Joseph Bowbeer, David Holmes & Doug Lea
There's a lot difference in having a deep knowledge on concurrency and know what a language can offer you to solve concurrency problems and taking advantage of multithreading.
In terms of performance, it depends on the current scenario.

C++ (and possibly Java) how are objects locked for synchronization?

When objects are locked in languages like C++ and Java where actually on a low level scale) is this performed? I don't think it's anything to do with the CPU/cache or RAM. My best guestimate is that this occurs somewhere in the OS? Would it be within the same part of the OS which performs context switching?
I am referring to locking objects, synchronizing on method signatures (Java) etc.
It could be that the answer depends on which particular locking mechanism?
Locking involves a synchronisation primitive, typically a mutex. While naively speaking a mutex is just a boolean flag that says "locked" or "unlocked", the devil is in the detail: The mutex value has to be read, compared and set atomically, so that multiple threads trying for the same mutex don't corrupt its state.
But apart from that, instructions have to be ordered properly so that the effects of a read and write of the mutex variable are visible to the program in the correct order and that no thread inadvertently enters the critical section when it shouldn't because it failed to see the lock update in time.
There are two aspects to memory access ordering: One is done by the compiler, which may choose to reorder statements if that's deemed more efficient. This is relatively trivial to prevent, since the compiler knows when it must be careful. The far more difficult phenomenon is that the CPU itself, internally, may choose to reorder instructions, and it must be prevented from doing so when a mutex variable is being accessed for the purpose of locking. This requires hardware support (e.g. a "lock bit" which causes a pipeline flush and a bus lock).
Finally, if you have multiple physical CPUs, each CPU will have its own cache, and it becomes important that state updates are propagated to all CPU caches before any executing instructions make further progress. This again requires dedicated hardware support.
As you can see, synchronisation is a (potentially) expensive business that really gets in the way of concurrent processing. That, however, is simply the price you pay for having one single block of memory on which multiple independent context perform work.
There is no concept of object locking in C++. You will typically implement your own on top of OS-specific functions or use synchronization primitives provided by libraries (e.g. boost::scoped_lock). If you have access to C++11, you can use the locks provided by the threading library which has a similar interface to boost, take a look.
In Java the same is done for you by the JVM.
The java.lang.Object has a monitor built into it. That's what is used to lock for the synchronized keyword. JDK 6 added a concurrency packages that give you more fine-grained choices.
This has a nice explanation:
http://www.artima.com/insidejvm/ed2/threadsynch.html
I haven't written C++ in a long time, so I can't speak to how to do it in that language. It wasn't supported by the language when I last wrote it. I believe it was all 3rd party libraries or custom code.
It does depend on the particular locking mechanism, typically a semaphore, but you cannot be sure, since it is implementation dependent.
All architectures I know of use an atomic Compare And Swap to implement their synchronization primitives. See, for example, AbstractQueuedSynchronizer, which was used in some JDK versions to implement Semiphore and ReentrantLock.

Categories

Resources