Java multithreading issue

Assume the following class

public class TestObject{ public void synchronized method1(){ //some 1000 lines of code } public void method2(){ //some 1000 lines of code } } 

Suppose that there are two threads accessing the same instance of the TestObject class, let t1 and t2 call them. I want to know what will happen in the following scenario.

  • When t1 is in the middle of accessing method 1 (). Now t2 is trying to access method2 ().
  • When t1 is in the middle of accessing method2 (). Now t2 is trying to access method1 ().

I understand that for the first question, the thread t2 will not get permission, since the object will be blocked by t1. On the second question, thread t2 will gain access and block the object and stop t1 from executing. But my guess was wrong. Can someone explain this?

thanks

+6
java multithreading
source share
6 answers

When you declare a method for synchronization, for example:

 public synchronized void foo() { // Do something } 

the compiler treats it as if you wrote this:

 public void foo() { synchronized (this) { // Do something } } 

In your example, you have one synchronized method and one unsynchronized. This means that only access to method1 will be blocked. Lock checks are only performed when entering the synchronized block, so calling method2 will not block.

To answer your two questions, in both cases, two threads will be allowed because they are not trying to get a lock on the same object. If you declare method2 for synchronization (or manually add a synchronized (this) block), then one thread will be forced to wait for another.

Remember: synchronization on an object does not interfere with other threads calling methods on this object. This only prevents another thread from appearing in the synchronized block with the same lock object.

By the way, it is often better to have an internal lock object rather than declare methods for synchronization, for example.

 class Foo { private final Object LOCK = new Object(); public void doSomething() { synchronized (LOCK) { // Whatever } } } 

Otherwise, I can violate thread safety by doing the following:

 class MessEverythingUp { public MessEverythingUp(Foo foo) { synchronized (foo) { while (true) { System.out.println("Pwnd ur thread safety"); } } } } 

Since I am locking the foo instance, your synchronized methods (with their implicit "synchronized (this)") will not be able to get the lock and will be locked forever. Most importantly, you cannot prevent this, because I can synchronize any object that I like. Obviously, the example is extreme, but you can get nasty, subtle bugs at a dead end if you are not careful about this.

+4
source share

Only a method with the synchronized keyword has a lock for this object when a thread is running in this method. If both methods 1 and method 2 were declared synchronized, one thread would block the other, even if they try to use different methods.
In your example, only 1 method blocks an implicit lock.
As a result, t1 and t2 can be executed simultaneously in method 1 and method 2 (or vice versa).
Only when trying to access method 1, t1 or t2 are blocked if a lock has already been received

+8
source share

In both cases, the second thread will be granted permission to execute its method.

Since only one of these two methods contains the synchronized , both of these methods can be executed simultaneously. The limitation is that only one method with this keyword can be executed at any time, because the execution of this method requires locking the object. A thread without a keyword does not require locking and will always be allowed to execute regardless of the locked object.

I also assume that 1000 lines of code in method2 do not contain such a block:

  synchronized (this) {
 }

If so, then the results will be different.

  • t2 will be allowed to start the method. When it gets into the synchronized line, it will wait for t1 method1 to complete and release its lock before continuing.
  • t2 will be allowed to start the method until t1 is in the synchronized code block. If so, t2 will wait until t1 exits the block and releases the lock before starting. If t1 has not yet entered a synchronized block, then t2 will receive a lock, and t1 will wait as soon as it enters the synchronized code block until t2 completes this method and releases the lock.
+3
source share

One method is synchronized, and the other is not. Thus, regardless of whether an object lock has been detected (in this case, the instance to which the method belongs), the unsynchronized method will execute unhindered (since it does not try to capture or wait for the lock). This means that in both cases, both threads will work without waiting for each other, which will lead to a possible inconsistent state of the object.

+2
source share

method1 () is synchronized and therefore called a thread safe method. When multiple threads try to access this method at the same time, then only the lock object on the instance will work.

method2 () is not synchronized and therefore is an unsafe thread method, other threads can call this method even if some other thread blocks the instance, therefore this method is called an unsafe thread method.

In both cases, you mentioned that one thread will get an instance lock by calling method1 (), and the other thread will try to access method2 (), which is unsafe and therefore both threads will execute.

subject to Tushar Joshi, Nagpur

0
source share

Both threads will execute as if the lock does not exist.

The access method to thread2 will never know that it should receive a lock, so it will be executed even if another thread holds the lock. Only synchronized methods will reserve a lock, because synchronization is optional and not always needed or even necessary.

If both threads execute method1, one of them will block until the other thread exits this method and releases the lock.

To make sure that only one thread is running and everyone else is waiting, you must synchronize both methods.

0
source share

All Articles