Can a seperate thread continue execution on an object synchronised by another? - java

Say I have an object A which has 2 methods:
public doSomething()
{....}
public synchronised doSomethingElse()
{ ... }
and I have thread1.doSomethingElse(), will it still be possible for thread2.doSomething() to execute or is it blocked by thread1's lock?
If so, how can I make thread1 execute at the same time?

There are two types of synchronization
1. Object level
2. Class level (Class level synchronization is for the static methods only.)
In your case since your methods are not static it is object level synchronization. For object level synchronization you can either synchronize your whole methods or you can synchronize some block of your methods.
When you synchronized one method. Its mean that same object of your class cant access your synchronized method from different threads. As each object have only one lock. If you had called doSomethingElse() for same obj but from different threads. Then It will be accessible by one thread.
Now comes to your answer:
As your first method is not synchronized i.e something(). It will not be effected in any case if you call it for any no of threads or even call it when your first thread is currently in the method. Locks are only for synchronized methods
Yourclass obj = new Yourclass();
Thread A = new MyThread(obj);
Thread B = new MyThread(obj);
......
public void run()
{
\\do what ever you want
\\both of your methods will be called.
\\ call them both here.
}
here i have made objects of same Mythread class you can do as per you want. you can make objects of two different implemented thread classes and write your run. In any case it will have no effect on the call.

Since thread 2 is not attempting to acquire any lock, it is not blocked and can run concurrently with thread 1. There's nothing special you need to do.

Related

Can two threads execute the same synchronized block of code on the same object if they use different monitors?

I'm newish to Java concurrency and I'm trying to better understand monitors.
Suppose I have one object, with a method that takes some kind of reference argument and uses that argument as a monitor in a synchronized block:
class Entity() {
public void myMethod(Object monitor) {
synchronized(monitor) {
// critical stuff
}
}
}
Can two threads enter that section at the same time on the same entity if they use different objects for the monitor?
final Entity myEntity = new Entity();
for (int i = 0; i < 3; i++) {
new Thread() {
public void run() {
// Can these all run concurrently?
myEntity.myMethod(new Object());
}
}.start();
}
If I understand monitors correctly, then yes, all the threads can enter the synchronized block at the same time, because each monitor acts as a totally different mutex and none of the threads are aware of the other threads in that block.
It's been difficult to find documentation on this because tutorials mostly seem to just use "this" as the monitor.
Can two threads enter that section at the same time on the same entity
if they use different objects for the monitor?
From the oracle tutorial one can read:
Every object has an intrinsic lock associated with it. By convention,
a thread that needs exclusive and consistent access to an object's
fields has to acquire the object's intrinsic lock before accessing
them, and then release the intrinsic lock when it's done with them. A
thread is said to own the intrinsic lock between the time it has
acquired the lock and released the lock. As long as a thread owns an
intrinsic lock, no other thread can acquire the same lock. The other
thread will block when it attempts to acquire the lock.
This informally means that one can synchronize using any Java Object. A block enclosed by a clause synchronized on a single object instance will be executed sequentially, i.e., executed by the thread holding the lock of the object being synchronized.
Can two threads enter that section at the same time on the same entity
if they use different objects for the monitor?
Yes, multiple threads can execute (in parallel) the same code region wrapped with a synchronized clause as long as each of those threads is synchronizing using different object instances.
One can also synchronize using the class itself, rather than its instances:
synchronized (SomeClass.class){
System.out.println("Hello World");
}
In such cases, all the threads that use the clause synchronized on the class SomeClass, will have to synchronize among each other.
One can also use clause synchronized on methods (e.g., public synchronized void method2()); for non-static methods the object being synchronized will be the object to which that method belongs, whereas for static methods (e.g., public static synchronized void method1()) will be class itself to which that method belongs.

Can two different objects like o1 and 02 of same class with different thead like t1 and t2 can they execute synchronized method at the same time

Assuming I have two different objects of same class, do they will able to execute the same synchronized method at the same time because the lock is on the object ant not on the method.
Example:
MyCLass cc= new MyCLass();
MyCLass cc1= new MyCLass();
Now create two thread
t1 --- it will call cc.meth
t2--it will call cc1.meth
// in this case t1 thread get lock on object cc and t2 thread get lock on object cc1.. it will work
synchronized meth(){
}
is it correct?
I think your question is answered here https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html, that tell that just one instance of the same class is locked while executing a synchronized method, obviously even if executed by a thread.
You are right. Synchronized methods lock their instance, not the class nor the method (for synchronized static methods, see below...).
So, on a given instance, only one thread can be inside any of its synchronized methods, but that does not block threads working with other instances of the same class.
Synchronized static methods lock the class (they don't have a this instance), so of all threads only one at a time can be executing inside a synchronized static method of the given class.
And if you need some other locking scheme, you can use a synchronized(someObject) { ... } block, which synchronizes on someObject, and then you are free to select the object that represents the mutual-exclusion group.
So, a synchronized method A.b() is equivalent to synchronized(this) {...} or (in the static case) synchronized(A.class) {...}.
synchronized implemented by monitorenter. You can see it in your byte code. monitorenter use the object monitor - the monitor of the instance of the class (not the class itself). So it is the expected behavior. If two threads try to execute synchronized methods of two different instances at the same time, both should not be blocked.
Actually it is better to avoid synchronized if the objects are not shared because synchronized is not good for performance. You should start thinking about synchronized only when you know that the object will be shared by more than one thread, which is not your case.
EDIT:
More simple explanation is that this code:
public synchronized void meth() {
...
}
equivalent to:
public void meth() {
synchronized (this){
...
}
}

Does Thread lock on object ensures lock on member objects too?

Consider following class that I have wrote for testing the locking of non-primitive variable (myObject). If all threads are working on same object instance of SynchronizationTest, my questions are:
I understand that if thread1 is executing set(...) method then any other thread (lets say thread2) is okay to execute either of the anotherSetWithSynchronized(...) or anotherSetWithoutSynchronized(...).
If thread1 has locked the object of SynchronizationTest while executing set(...), does it mean it has acquired lock on all member object variable ? like in this case myObject. If not then,
If thread1 is executing set(...) can thread2 execute anotherSetWithSynchronized(...) concurrently?
Are none of the two methods can execute simultaneously by thread?
Is this design wrong? Do I need to explicitly lock myObject in synchronized set(...) method. Like this:
public synchronized void set(MyValue myValue) {
synchronized (myObject) {
myObject.put(myValue);
}
}
Here's my code:
public class SynchronizationTest {
private MyObject myObject = new MyObject();
public synchronized void set(MyValue myValue) {
myObject.put(myValue);
}
public void anotherSetWithSynchronized(MyValue myValue) {
synchronized (myObject) {
myObject.put(myValue);
}
}
public void anotherSetWithoutSynchronized(MyValue myValue) {
myObject.put(myValue);
}
}
1: No, set(...) method is guarded by "SynchronizationTest" Object's lock.
2: Yes, their guard objects are different as you've designed.
3: One thread can only run one method per time. If you mean two threads, as I've explained, the methods are guarded by two objects and therefore they can be executed simultaneously
4: Yes, you're right.
The intrinsic lock in Java is described as follows in the book "Java Concurrency In Practice":
A synchronized block has two parts: a reference to an object that
will serve as the lock, and a block of code to be guarded by that
lock. A synchronized method is shorthand for a synchronized block
that spans an entire method body, and whose lock is the object on
which the method is being invoked. (Static synchronized methods use
the Class object for the lock.)
For more details, you can refer to section 2.3.1 of "Java concurrency in Practice".
synchronized method is equivalent to
public void method(){
synchronized(this){
//something
}
}
1) no
Synchronization is only on specified objects, not on its members.
2) no
3) yes, they cannot, only one thread can be active inside synchronized section guarded by given monitor
4) you don't need to (and you should not use synchronized on method level if you are using explicit synchronization). BUT its better (for libraries/large codebase), because then you can controll who can acces instance on which synchronization occurs, so someone other can't synchronize on it and cause deadlock.
Does Thread lock on object ensures lock on member objects too?
No.
I understand that if thread1 is executing set(...) method then any other thread (lets say thread2) is okay to execute either of the anotherSetWithSynchronized
Yes, unless myObject has the same value as 'this'.

if i call a non synchronized method from my synchronized method is non synchronized method thread safe?

I i make a call to noonsynchronized method from within my synchronized method is it thread safe?
I have 2 methods as follows:
public class MyClass{
void synchronized doSomething1(){
doSomething2();
}
void doSomething2(){
//will this block of code be synchronized if called only from doSomething1??
}
}
If doSomething2() is only called from doSomething1(), then it will only be called by a single thread for a single instance of MyClass. It could still be called from different threads at the same time, via different instances - so if it acts on any shared data which may not be specific to the instance of MyClass, it's still not guaranteed to fix all threading issues.
Basically, you need to think carefully about any mutable shared state used by multiple threads - there are no easy fixes to that, if you need mutable shared state. In your particular case you'd also need to make sure that doSomething2() was only called from doSomething1() - which would mean making it private to start with...
When calling doSomething1() the caller's Thread locks on the monitor of the instance of MyClass. Until that thread's execution exits doSomething1 the lock will remain which includes if it goes into doSomething2. This will cause other threads to block when attempting to lock.
Keep in mind:
synchronized does not thread-safe it make.
Further info:
JLS 3rd Ed 17.1 Locks
If doSomething2() is called ONLY from doSomething1() then yes - it is thread safe.

question about singleton classes and threads

I'm trying to learn about singleton classes and how they can be used in an application to keep it thread safe. Let's suppose you have an singleton class called IndexUpdater whose reference is obtained as follows:
public static synchronized IndexUpdater getIndexUpdater() {
if (ref == null)
// it's ok, we can call this constructor
ref = new IndexUpdater();
return ref;
}
private static IndexUpdater ref;
Let's suppose there are other methods in the class that do the actual work (update indicies, etc.). What I'm trying to understand is how accessing and using the singleton would work with two threads. Let's suppose in time 1, thread 1 gets a reference to the class, through a call like this IndexUpdater iu = IndexUpdater.getIndexUpdater(); Then,
in time 2, using reference iu, a method within the class is called iu.updateIndex by thread 1. What would happen in time 2, a second thread tries to get a reference to the class. Could it do this and also access methods within the singleton or would it be prevented as long as the first thread has an active reference to the class. I'm assuming the latter (or else how would this work?) but I'd like to make sure before I implement.
Thank you,
Elliott
Since getIndexUpdater() is a synchronized method, it only prevents threads from accessing this method (or any method protected by the same synchronizer) simultaneously. So it could be a problem if other threads are accessing the object's methods at the same time. Just keep in mind that if a thread is running a synchronized method, all other threads trying to run any synchronized methods on the same object are blocked.
More info on:
http://download.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
Your assumption is wrong. Synchronizing getIndexUpdater() only prevents more than one instance being created by different threads calling getIndexUpdater() at (almost) the same time.
Without synchronization the following could happen: Thread one calls getIndexUpdater(). ref is null. Thread 2 calls getIndexUpdater(). ref is still null. Outcome: ref is instantiated twice.
You are conflating the instantiation of a singleton object with its use. Synchronizing the creation of a singleton object does not guarantee that the singleton class itself is thread-safe. Here is a simple example:
public class UnsafeSingleton {
private static UnsafeSingleton singletonRef;
private Queue<Object> objects = new LinkedList<Object>();
public static synchronized UnsafeSingleton getInstance() {
if (singletonRef == null) {
singletonRef = new UnsafeSingleton();
}
return singletonRef;
}
public void put(Object o) {
objects.add(o);
}
public Object get() {
return objects.remove(o);
}
}
Two threads calling getInstance are guaranteed to get the same instance of UnsafeSingleton because synchronizing this method guarantees that singletonRef will only be set once. However, the instance that is returned is not thread safe, because (in this example) LinkedList is not a thread-safe queue. Two threads modifying this queue may result in unexpected behavior. Additional steps have to be taken to ensure that the singleton itself is thread-safe, not just its instantiation. (In this example, the queue implementation could be replaced with a LinkedBlockingQueue, for example, or the get and put methods could be marked synchronized.)
Then, in time 2, using reference iu, a method within the class is called iu.updateIndex by thread 1. What would happen in time 2, a second thread tries to get a reference to the class. Could it do this and also access methods within the singleton ...?
The answer is yes. Your assumption on how references are obtained is wrong. The second thread can obtain a reference to the Singleton. The Singleton pattern is most commonly used as a sort of pseudo-global state. As we all know, global state is generally very difficult to deal with when multiple entities are using it. In order to make your singleton thread safe you will need to use appropriate safety mechanisms such as using atomic wrapper classes like AtomicInteger or AtomicReference (etc...) or using synchronize (or Lock) to protect critical areas of code from being accessed simultaneously.
The safest is to use the enum-singleton.
public enum Singleton {
INSTANCE;
public String method1() {
...
}
public int method2() {
...
}
}
Thread-safe, serializable, lazy-loaded, etc. Only advantages !
When a second thread tries to invoke getIndexUpdater() method, it will try to obtain a so called lock, created for you when you used synchronized keyword. But since some other thread is already inside the method, it obtained the lock earlier and others (like the second thread) must wait for it.
When the first thread will finish its work, it will release the lock and the second thread will immediately take it and enter the method. To sum up, using synchronized always allows only one thread to enter guarded block - very restrictive access.
The static synchronized guarantees that only one thread can be in this method at once and any other thread attempting to access this method (or any other static synchronized method in this class) will have to wait for it to complete.
IMHO the simplest way to implement a singleton is to have a enum with one value
enum Singleton {
INSTANCE
}
This is thread safe and only creates the INSTANCE when the class is accessed.
As soon as your synchronized getter method will return the IndexUpdater instance (whether it was just created or already existed doesn't matter), it is free to be called from another thread. You should make sure your IndexUpdater is thread safe so it can be called from multiple threads at a time, or you should create an instance per thread so they won't be shared.

Categories