Can two threads run two different methods at the same time?

class A { private synchronized f() { ... ... } private void g() { ... ... } } 

If thread T1 runs f (), which is synchronized, can you run t2 run g (), which is not synchronized at the same time, while T1 is still running f ()?

+7
java multithreading
source share
7 answers

Not in the same instance A. The instance itself is a lock, so two execute two methods simultaneously with two threads, you will need two instances of A.

+16
source share

Yes. Both methods can be executed simultaneously in one instance.

Only f() synchronized. The thread should get a monitor for this.f() to execute f() , and only one monitor exists per instance.

g() not synchronized, the monitor lock is not required to start the method, so any thread can execute g() at any time.

"The synchronized method receives the monitor (Β§17.1) before it is executed."

http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.3.6

+5
source share

Not. One call is blocked until another is completed. The reason for this is that the synchronized keyword in the method expands to synchronize in the current instance of the object. To be more specific, consider this code:

 private void synchronized f () {
   ...
 }

The code above is identical in functionality to the following code:

 private void f () {
   synchronized (this) {
     ...
   }
 }

So, if you want the two methods in the object to synchronize only with each other, you must create two lock objects. Each method should wrap all its code inside the synchronization block (object), one object for each method.

+4
source share

Yes, if T1 and T2 are executed f and g respectively in different copies of A.

If both threads execute the method on the same instance of A, only one of them will be able to execute the method at a time. If T1 starts first, it will get a lock on instance A and execute method f . Thread T2 will not be able to execute method g until T1 finishes executing f . Or the opposite may happen: T2 can start g first, and T1 cannot start f until T2 completes.

+3
source share

In general, two threads can run two methods at the same time; however, in your example, only one thread can run f() or g() at any time.

Using the synchronized changes the interaction of threads. Each Java object has a lock, an element that can contain only one thread at a time. synchronized is a command that directs threads to obtain a lock before executing a method and releases it after that. The lock is maintained during the entire execution of the method.

In your example, only one thread will execute f() or g() at any given time, because the β€œother” thread will wait its turn to capture the lock.

If you have two objects of the same class, you have two locks. This means that you can get two threads to run f() and g() at the same time with the synchronized keywords without changes, since the threads will capture locks on different objects. You simply cannot force threads to run simultaneously on the same object without removing the synchronized .

+2
source share

The correct answer to this question is re-assembler.

Run this and you will see. You can also test using Thread.sleep () instead of an infinite loop by uncommenting / commenting on the relevant sections of the sample.

I apologize if the code does not match the best methods, my java is pretty rusty.

 package threadtest; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; public class ThreadTest { /** * @param args the command line arguments */ public static void main(String[] args) throws IOException { TestClass tc = new TestClass(); // invokes not sync method FirstThreadRunnable ftr = new FirstThreadRunnable(tc); Thread t1 = new Thread(ftr); // invokes the sync method SecondThreadRunnable str = new SecondThreadRunnable(tc); Thread t2 = new Thread(str); t2.start(); t1.start(); System.in.read(); } public static class TestClass { private int callCount = 0; public void notSynchronizedMethod() { System.out.println("notSynchronizedMethod says hello!" + " [" + callCount++ +"] from thread: " + Thread.currentThread().getId()); } public synchronized void synchronizedMethod() throws InterruptedException { // Test with the sleep //System.out.println("entering sync method and pausing from thread: " + Thread.currentThread().getId()); //Thread.sleep(5000); // hold the monitor for 5sec //System.out.println("exiting sync method" + " [" + callCount++ +"] from thread: " + Thread.currentThread().getId()); // Test with spinning System.out.println("MAKE IT SPIN! from thread: " + Thread.currentThread().getId()); boolean spin = true; while(spin){ } System.out.println("IT STOPPED SPINNING! from thread: " + Thread.currentThread().getId()); } } // invokes the not sync method public static class FirstThreadRunnable implements Runnable { TestClass tester = null; public FirstThreadRunnable(TestClass tester){ this.tester = tester; } @Override public void run() { for(int i = 0; i < 500; i++){ tester.notSynchronizedMethod(); try { Thread.sleep(50); } catch (InterruptedException ex) { Logger.getLogger(ThreadTest.class.getName()).log(Level.SEVERE, null, ex); } } } } // invokes the sync method public static class SecondThreadRunnable implements Runnable { TestClass tester = null; public SecondThreadRunnable(TestClass tester){ this.tester = tester; } @Override public void run() { try { // Test with Sleep() //for(int i = 0; i < 5; i++){ // tester.synchronizedMethod(); //} // Test with the spinning tester.synchronizedMethod(); } catch (InterruptedException ex) { Logger.getLogger(ThreadTest.class.getName()).log(Level.SEVERE, null, ex); } } } } 
+2
source share

for interest in technicality and pedantry, yes, both methods can be introduced at the same time. one is locked on synchronized (this), at least, the method is entered and launched, its first statement is executed and the first byte code instruction is executed.

0
source share

All Articles