Mutex in Java 1.4 [duplicate] - java

This question already has answers here:
Java 1.4 synchronization: only allow one instance of method to run (non blocking)?
(4 answers)
Closed 6 years ago.
I need to isolate function myFunc() from executing from several threads. I know how to solve this task with Mutex. Since Java 1.4 not supports Mutex how to solve this task in another way?

In Java all objects have an intrinsic lock, also called a monitor lock. This is enough to provide simple mutual exclusion but it does have limitations.
public final class MyClass1 {
public synchronized void myFunc() {
// Exclusive work here
}
}
The synchronized keyword on the method means that the intrinsic lock of the MyClass1 object instance must be acquired before myFunc can run.
public static final class MyClass2 {
private final Object mutex = new Object();
public void myFunc() {
synchronized (mutex) {
// Exclusive work here
}
// There is no mutual exclusion here
}
}
A block inside of a method can be synchronized for the scope of the block. This also allows you chose the object to acquire the lock of.
An intrinsic lock will either be acquired eventually or the thread will hang. An attempt to acquire an intrinsic lock does not timeout and cannot be interrupted.
An intrinsic lock is reentrant so you do not need to worry about a thread deadlocking with itself. Deadlocks can still happen when acquiring locks in different orders.
The synchronized keyword also ensure memory visibility of reads and write when they both take place in a synchronised code that locks the same object.
https://docs.oracle.com/javase/tutorial/essential/concurrency/locksync.html
https://docs.oracle.com/javase/tutorial/essential/concurrency/memconsist.html
You should also know that the Java memory model has changed since 1.4 so much of the current information will not be applicable.
https://www.ibm.com/developerworks/library/j-jtp03304/

Related

Why do we need to pass arguments in Synchronized Statements in java? [duplicate]

This question already has answers here:
What is the purpose of passing parameter to synchronized block?
(3 answers)
Closed 5 years ago.
I was reading about synchronization concept in java and came across synchronized statements .
I want to know , why do we pass arguments to it , though it appears like static block(it's just an example) , and the arguments passed do not have any data type specified with it .
Example :
public class MsLunch {
private long c1 = 0;
private long c2 = 0;
private Object lock1 = new Object();
private Object lock2 = new Object();
public void inc1() {
synchronized(lock1) {
c1++;
}
}
public void inc2() {
synchronized(lock2) {
c2++;
}
}
}
If any one knows about it , please explain .
In a multithreaded application when you want the states of an object to be read and written in a synchronized way by multiple threads then you use synchronized keyword.
The mechanism that Java uses to support synchronization is the monitor. Each object has a monitor associated with it. Synchronized block needs an object to work with, so that the threads in competition can compete and the winner thread can aquire the monitor.
Each non static method in java has an implicit this object upon which the particular method is invoked. If you use synchronized keyword in the method signature then it means you are depending upon the implicit this object for synchronization. If you wish to depend upon any other object then you can use the synchronized blocks and use the object reference in it.
Remember there may be various synchronized blocks but the blocks with synchronized block on same object will only gurantee the proper syncronized execution with respect to each other. Synchronized Blocks which have references of different objects do not force threads to work in synchronized way.
Thus Suppose when there is some threadA which modifies some states of an objectX and works with synchronized block with ObjectA. There may be another piece of code may be in some other class where some other threadB may be reading the states of the same objectX. Now threadB should also do the reading within a synchronized block with ObjectA so that states of objectX are read properly.

Recursive Synchronization vs Recursive Reentrant Lock

I know thread is allowed to acquire a monitor owned by itself i.e. In Java, synchronized locks are reentrant as shown in example below.
My query is if i use java.util.concurrent.locks.ReentrantLock API it will produce the same result or not, Can we have dead lock in synchronized but never in java.util.concurrent.locks.ReentrantLock
e.g.
final Object[] objects = new Object[10]
public synchronized Object setAndReturnPrevious(int index, Object val) {
lock.lock();//If i use this will it be same as above synchronization
set(index, val);
lock.unlock()//;
}
public synchronized void set(int index, Object val) {
lock.lock();//
objects[index] = val;
lock.unlock();//
}
If you look at the Java doc (here) and the point is very clear (emphasis mine):
A reentrant mutual exclusion Lock with the same basic behavior and
semantics as the implicit monitor lock accessed using synchronized
methods and statements, but with extended capabilities. A
ReentrantLock is owned by the thread last successfully locking, but
not yet unlocking it. A thread invoking lock will return, successfully
acquiring the lock, when the lock is not owned by another thread. The
method will return immediately if the current thread already owns the
lock.
The main point is that they both behave with the same concept, but ReentrantLock lock provides additional methods to lock()/unlock()/etc.. methods which you can use them explicitly in different code blocks (methods).
Both synchronized and reentrant locks are same . if you want more control and want to solve complex synchronization problems than Reentrant Lock is the best choice. it adds additional functionality to the implicit synchronization like ** support for Condition variables , Lock Fairness etc.**
As a Reference Check Java Threads 3rd Ed - Chapter 3 and Onwards

Java Lock explanation

I can't understand the following code:
public class Counter {
private long value;
private Lock lock;
public long getAndIncrement() {
lock.lock();
try {
int temp = value;
value = value + 1;
} finally {
lock.unlock();
}
return temp;
}
}
What I can't understand is how Lock is instantiated while it's an interface?
And if it's an anonymous class that implements Lock interface, why I can't see any override of Lock functions (e.g. lock() and unlock() ) ?
In short, the following line really confuses me.
private Lock lock;
What is lock here? What is its type?
Edit:
Lock is an interface and can't be instantiated. After looking at the constructor:
public Counter(){
lock = new ReentrantLock();
}
Now, everything is clear. (Thanks to Bhushan Uniyal )
Q how Lock is instantiated while it's an interface?
Lock in an interface, implemented by ReentrantLock, ReentrantReadWriteLock.ReadLock, ReentrantReadWriteLock.WriteLock
From Java Doc
A reentrant mutual exclusion Lock with the same basic behavior and
semantics as the implicit monitor lock accessed using synchronized
methods and statements, but with extended capabilities.
A ReentrantLock is owned by the thread last successfully locking, but
not yet unlocking it. A thread invoking lock will return, successfully
acquiring the lock, when the lock is not owned by another thread. The
method will return immediately if the current thread already owns the
lock. This can be checked using methods isHeldByCurrentThread(), and
getHoldCount().
The constructor for this class accepts an optional fairness parameter.
When set true, under contention, locks favor granting access to the
longest-waiting thread. Otherwise this lock does not guarantee any
particular access order. Programs using fair locks accessed by many
threads may display lower overall throughput (i.e., are slower; often
much slower) than those using the default setting, but have smaller
variances in times to obtain locks and guarantee lack of starvation.
Note however, that fairness of locks does not guarantee fairness of
thread scheduling. Thus, one of many threads using a fair lock may
obtain it multiple times in succession while other active threads are
not progressing and not currently holding the lock. Also note that the
untimed tryLock method does not honor the fairness setting. It will
succeed if the lock is available even if other threads are waiting.
lock()
Acquires the lock.
Acquires the lock if it is not held by another thread and returns
immediately, setting the lock hold count to one.
If the current thread already holds the lock then the hold count is
incremented by one and the method returns immediately.
If the lock is held by another thread then the current thread becomes
disabled for thread scheduling purposes and lies dormant until the
lock has been acquired, at which time the lock hold count is set to
one.
Lock is a interface and you need to provide it implementation of Lock, there are already some classes which provide the implementation of Lock , ReentrantReadWriteLock.ReadLock, ReentrantLockReentrant, ReadWriteLock.WriteLock,
e.g;
Lock lock = new , ReentrantLockReentrant();
also you can provide your own implementation
public class MyLock implements Lock {
public void lock() {
}
public void lockInterruptibly() throws InterruptedException {
}
public boolean tryLock() {
return false;
}
public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
return false;
}
public void unlock() {
}
public Condition newCondition() {
return null;
}
}
A lock is a thread synchronization mechanism like synchronized blocks except
locks can be more sophisticated than Java's synchronized blocks. Locks (and other more advanced synchronization mechanisms) are created using synchronized blocks, so it is not like we can get totally rid of the synchronized keyword.
From Java 5 the package java.util.concurrent.locks contains several lock implementations, so you may not have to implement your own locks. But you will still need to know how to use them, and it can still be useful to know the theory behind their implementation.

Does deadlock happen per method or per class?

Immagine that I have Class First with several synchronised methods. When a thread locks the class First, does it lock per method or per class? For example does deadlock happen for the following code?
public class DeadLockQuestion {
public static class First{
public synchronized void a(){
}
public synchronized void b(){
}
public synchronized void c(){
}
public synchronized void d(){
}
public synchronized void e(){
}
}
public static void main(String... args){
First f = new First();
//This code is run in Thread 1
f.a();
// End
//This code is run in Thread 2 simultanously
f.b();
//End
// We have also Threads 3 & 4 & 5 that invoke c,d and e simultanously
}
}
You have got two locks in Java. One is Object lock. and the other is Class Lock.
The object lock locks access to synchronized non-static functions only. and Class lock locks on synchronized static functions only.
For you, its an object lock on object f. So all the synchronized non-static functions are locked for object f.
Since all the Threads are using the same object f, Only one Thread will be able to access your non-static functions a(), b(),... at a time.
Read more here
does deadlock happen for the following code?
No, it won't happen in your case. Because While one Thread is holding the lock, Other threads can't get inside your synchronized function.DeadLock happens due to resources.
You have only one resource thats Object f. There's no point of a dead-lock here because the class First doesn't lock another object and no cyclic lock can happen. Deadlock requires a cyclic lock!
Some Info:
Synchronization in java guarantees that no two threads can execute a
synchronized method which requires same lock simultaneously or
concurrently.
synchronized keyword can be used only with methods and code blocks.
These methods or blocks can be static or non-static both.
When ever a thread enters into java synchronized method or block it
acquires a lock and whenever it leaves java synchronized method or
block it releases the lock. Lock is released even if thread leaves
synchronized method after completion or due to any Error or
Exception.
It’s possible that both static synchronized and non static
synchronized method can run simultaneously or concurrently because
they lock on different object.
Useful Source Here, and here
Deadlock happens to threads, not to methods or classes.
The deadlocked threads also hold locks, but in this case it is impossible to tell which locks because you do not demonstrate an actual deadlock scenario (if two threads call synchronized methods of f one goes through and the other waits; deadlock requires at least two locks).
To lock each method independently use a synchronized block within each method and lock on a different object.
If you have an appropriate (and it should be final to prevent potential problems) object already within the class you can use that. If not create a private final Object aLock = new Object(); and then lock on that, for example:
private final Object aLock = new Object();
public void a() {
synchronized(aLock) {
// Do stuff that needs the lock
}
// do stuff that doesn't need the lock
}
Always hold the lock for as long as you need it, but no longer.
When a() is a synchronized method, f.a() literally means:
synchronized(f){
f.a();
}
So in this case a lock would happen for object monitor f. In your case you would require a second object to create a deadlock, I don't think it's possible to create a deadlock with a single object monitor. A typical deadlock pattern is when an order of lock acquisition is not being maintained, i.e. when this happens in two different threads:
synchronized(a){
synchronized(b){
...
}
}
// and
synchronized(b){
synchronized(a){
...
}
}
Firstly, Deadlock occurs with threads and not classes or methods.
Deadlock occurs when there is a cyclic dependency of locks.
Thread A ---> locks L1 ---> tries to lock L2
Thread B ----> locks L2 ------> tries to lock L1
Image source: FusionReactor deadlock plugin

Synchronized threads and locking

Can someone please explain the difference between these two examples in the context of object locking:
public void method1(){
synchronized(this){
....
}
}
And
StringBuffer aStringBufferObject = new StringBuffer("A");
public void method2(){
synchronized(aStringBufferObject){
....
}
}
I know the first example will obtain a lock on the this instance and the second will obtain a lock of the aStringBufferObject instance. But i dont really understand what the effect or the difference of the two is.
For example, in the second example, will threads still be able to execute the code inside the synchronized block because the lock is not related to the 'this' instance?
I know that synchronizing a method or a block of code prevents multiple threads to access that block/method at the same time but what is the purpose of specifying the object to lock on and what is the difference in the way the object is specified as in the above examples?
What is the purpose of specifying the object to lock on?
Often, it is easier to synchronize on this or on the Class instance (for static methods). But, there are cases where you will need to synchronize on a specific object instead of the implicit lock (this). Such cases include:
You want to synchronize access to primitives without using this. You can only synchronize on Objects as each Object is associated with an implicit monitor in Java. Primitives do not have such implicit monitors, and therefore you need to use a lock object. Using the wrapper classes are a poor and incorrect choice, especially if you end up modifying the lock object in the guarded block.
You want to synchronize on an object that actually protects the critical section, when synchronizing on this would not offer a guarantee of thread safety. For instance, if you are synchronizing access to a ArrayList instance shared across instances of class A, then synchronizing on an instance of A is useless. A thread might create a new instance of A and gain access to the list, while another thread is modifying it. If you use a different lock that all threads must contend for then you can protect the list; this lock could be the one associated with A.class, but it could be any object that will offer the same guarantees.
You want to perform lock splitting to ensure that different guarded blocks are protected by different locks instead of the same lock. In other words, if it is thread-safe to allow different threads to acquire different locks to access different critical sections, then you can have a different lock for every critical section.
The following is an example of split lock usage:
private Object method1Lock = new Object();
private Object method2Lock = new Object();
public void method1(){
synchronized(method1Lock){
....
}
}
public void method2(){
synchronized(method2Lock){
....
}
}
You would use split locks when you can ensure that the concurrent execution of method1 and method2 do not violate the class invariants. This way, you can improve performance across threads that need access to the same object, but will be invoking different methods.
On your other question,
For example, in the second example, will threads still be able to execute the code inside the synchronized block because the lock is not related to the 'this' instance?
In the second example, any thread entering the guarded region must acquire the lock associated with aStringBufferObject. If a different thread is holding that lock, then the current thread will not proceed further. When you specify this, then the thread must acquire the lock associated with the current object. In both cases, a thread must acquire a lock; the examples are only different in the object that is being used as a lock.
Synchronizing on an object means that other blocks which synchronize on the same object will have to wait. For example:
public void methodA() {
synchronized(obj) {
//Do one job
}
}
public void methodB() {
synchronized(obj) {
//Do another job
}
}
If you call methodA() in one thread and then call methodB() in another thread, methodB() won't finish before methodA() finishes.
The synchronized block is a monitor, which leave out of details to lock and unlock a mutex. Because every object in Java has an internal lock(refer to source code of Object class), when use synchronized statement, the JVM will help you synchronize the critical section. You can also synchronize block yourself use ReentrantLock in package java.util.concurrent.locks.

Categories

Resources