views:

71

answers:

4
Class ThreadTest extends Thread {
  public synchronized void run() {

  }

  public static void main(String args[])
  {
    Thread t1=new ThreadTest();
    Thread t2=new ThreadTest();
    t1.start();
    t2.start();
  }
}

I want to know in above scenario, how locks obtained and on which object? Does above scenario valid? As locks are obtained on a calling object in method synchronisation then in above scenario on which object lock will be obtained. One more question who(or which object) invokes the run method?

Thanks, -Abhishek

A: 

Your example doesn't make that much sense, because locks are on a per-instance level, not on a per-class level as you might wanted to use them.

I think you got it wrong a bit. The thread is wrapping up the code that is executing commands. These executions often contain access on other objects. That is the point, where locking comes into the game. Each of these objects have a monitor that can be obtained by threads. However, only one thread can obtain the lock at a time. Thus, other threads are enqueued and can access object as soon as the current holder releases it, trivially by exiting a synchronized code block.

I think you might wanted to do something like this:

class ThreadTest extends Thread
{
    private final Foo f;

    public ThreadTest(Foo f,int i)
    {
        super(""+i);
        this.f = f;

    }

    @Override
    public void run()
    {
        f.bar();
    }

    public static void main(String args[])
    {

        Foo f = new Foo();
        Thread t1 = new ThreadTest(f,1);
        Thread t2 = new ThreadTest(f,2);
        t1.start();
        t2.start();
    }

    public static class Foo
    {
        public synchronized void bar()
        {
            System.out.print("hello form Thread ");
            System.out.println(Thread.currentThread().getName());
        }

    }

}
PartlyCloudy
A: 

You have started both the threads, but it depends on JVM which thread it might execute, so depending upon the thread which starts executing will acquire the lock first and the second thread cant be on running state till the first thread stops.

but in your case as both are different thread instances they run parallel, as the lock is acquired at the object level.

GK
A: 

Formal Definition

When a thread invokes a synchronized method, it automatically acquires the intrinsic lock for that method's object and releases it when the method returns. The lock release occurs even if the return was caused by an uncaught exception.


If what you want is to have only one thread execute at a time (What's the point) then you should call a static method and call that from inside your run(), there is only one static method for all object of a class http://stackoverflow.com/questions/578904/how-do-synchronized-static-methods-work-in-java

Romain Hippeau
No, the run method will be executed by both threads. They are different instances and different locks..
Prine
@Hugo Walker - you were correct - fixed post, thx
Romain Hippeau
+2  A: 

t1 has the lock of the t1 instance.
t2 has the lock of the t2 instance.

But your example doesnt make much sense..

Maybe this example will help you:

public class Test extends Thread  {

private String name;

public Test(String name) {
    this.name = name;
}

public synchronized void run() {
    System.out.println(name);

    while(true) 
        { 
        // loop endless
        }
  }

  public static void main(String args[])
  {
    Thread t1= new Test("t1");
    Thread t2= new Test("t2");
    t1.start();
    t2.start();

  }

}

The output is:

t1
t2
Prine
@Hugo I have one more doubt. Thread t1/t2 object calls only start() method, not run() method. i think scheduler decides the invocation of the run() method but who invoke run() method actually. Is it t1/t2 object?
Abhishek Jain
The `start()` does all the bootstrapping stuff in order to spawn the new thread and evenutally invokes the `run()` method.
PartlyCloudy
You can read it in the api documentation of Thread. The start() method actually calls the run() method. Here the sentence from the api Thread.start() doc: "Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread." So its the Java Virtual Machine which actually invokes the run method.
Prine