Synchronization Mechanism in Java

As we all known, multi-threads compete for the same resource, where the sequence of in which the resource is accessed by threads is significantly affected the result of the execution of the section of code is called race condition. A code section leading to this racing condition is Critical Section.
When we write down the code for multi-thread execution, we usually only have on expected result. so we have to control the execution of critical section, to make sure it only executed by only one thread at per time. This is exactly the synchronization mechanism designed for. Proper synchronization mechanism in Java includes Synchronized Blocks, Locks, and Atomic variable.

1. Synchronized Blocks

Java provide synchronized key word for synchronization, when writing code, you can specify a critical section using two approaches:
1> synchronized(object) {…}
2> synchronized method(args) {…}

the first option is for declaring a synchronized block, before entering this critical section, a thread need to check if the declared object was locked by another threads, the mark word of the object contains two bits to illustrate this.
the second option is declaring the whole method is a synchronized block, and use ‘this’ as the lock. The related bytecode for instructing JVM for acquiring monitor is added before and after the code where call this method.
As the standard monitor mechanism required, every thread need to acquire the mutex before occupying the monitor to execute the critical section, and if it failed to acquire the mutex, the thread will enter a enter queue, and after the current occupying thread release the mutex, the only thread could have opportunity to try acquire the lock then occupy the monitor.
But put a thread into a waiting/enter queue and mark it as waiting, and recoveried back afterward is a expensive operation for CPU, especially for the low-level concurrency and the duration for execution the critical section is short.
Since java6, JVM optimized the mechanism for synchronized key word. When a object is first locked for acquiring the monitor, the mark word of the object changed from 01 to 00, and the thin lock mechanism is used. basically, it will enter the critical section directly, and assume there is no competition with any other threads. Following thread for locking this object, will spin itself and wait until the thread who occupied the monitor release the lock by changing the mark word to 01 again. When too many thread compete for the lock, JVM will inflate the lock, then mark word change to 10 to using the heavy lock mechanism. Things go back to the standard monitor process.
But even CAS has performance problems, although model CPU architecture offered CAS operation in instruction level, it still need to guarantee the atomic executing of the CAS operation itself. For example, two thread is spinning waiting for the entering the critical section. those spin operations was checking the lock status of the object, and once the status of the object changed, we need to guarantee only one thread is able to change it. This means we need to whole CAS operation is atomic. So, basically, CAS operation is using a small synchronized critical section to replace the long synchronized critical section.
To solve the performance issue of CAS, java6 also introduced baised lock, even slighter than thin lock. It is for the lowest concurrency senario, another bit in mark word of an object indicate if the lock is baised or not. For baised lock, only the first lock acquisition performs an atomic CAS to install an ID of the locking thread into the header word of the object. then, the object is said to be baised towards the thread. Future locking and unlocking of the objet by the same thread only perform a special CAS operation without atomic executing. The tricky part is about split the CAS operation into mark and spin two stage, instead of the atomic spin operation. Too many competitions of thread is not suitable for baised lock, if an application is predictable to utilized the competition of the threads like producer/consumer mode, it is not suitable for baised locking. also, JVM have an option to disable the baised lock.

2. ReentrantLock

ReentrantLock is the lock provide by java in language level to implement monitor. The behavier is similar to the heavy-weight mode of synchronized block. The advantages of ReentrantLock is offered more flexiablity to lock an object. With reentrant lock, you are able to create an monitor overthrough different methods. And it also provide fair and non-fair mode, for the different strategy of choose the queued threads to obtain the lock.
ReentrantLock is a pessimistic locking, it assumes that there will be many conflicts on the resources accessing in the program. so, before a thread executing the critical section, it requiues to obtain the lock to prevent other thread entering the critical section. And if one thread failed to obtain the lock, it will halt, and enter the waiting queue.

3. AtomicObject

AtomicObject the optimistic locking provide by java in language level. the mechanism is similar to the thin lock of JVM. It is much cheaper than reentrantLock, however, it can only guarantee the operation to itself is atomic. It can’t synchronize the two different operations on different resources.

4. ReadWriteLock

Compare to talk about the underline mechanism, ReadWriteLock is more sophisticated, we usually care more about the usage of the this Lock. It provide the different locking mode for read and write operation to a resource. read thread didn’t block each other, while write thread blocks both read and write threads.

5. Semaphore

Semaphore is more like a lock which allows multi-thread entered the ‘Critical Section’, it is designed to be a threshold of the throughput of thread execution instead of control the access to a resource to prevent the error behavier. Although the underline mechanism is similar, just, no need to think too much about the consequence of race condition of threads. One of the feature of semaphore, it support to siginal the thread from another thread which is convenient for solve deadlock issue. And if you limit the number of thread for the semaphore to 1, it then will be functioning as a lock, but support to recieve an command to release the lock from another thread.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值