Java 如何在多线程中获得锁?在哪个对象上?

Java 如何在多线程中获得锁?在哪个对象上?,java,multithreading,Java,Multithreading,我想知道在上面的场景中,锁是如何获得的,在哪个对象上? 上述情景有效吗? 由于在方法同步中在调用对象上获得锁,那么在上面的场景中,将获得对象锁。还有一个问题谁(或哪个对象)调用run方法? 谢谢, -Abhishek您的示例没有太大意义,因为锁是在每个实例级别上的,而不是您可能希望使用的每个类级别上的 我想你弄错了一点。线程正在包装执行命令的代码。这些执行通常包含对其他对象的访问。这就是锁定进入游戏的关键所在。每个对象都有一个可以通过线程获得的监视器。但是,一次只能有一个线程获得锁。因此,其他线

我想知道在上面的场景中,锁是如何获得的,在哪个对象上? 上述情景有效吗? 由于在方法同步中在调用对象上获得锁,那么在上面的场景中,将获得对象锁。还有一个问题谁(或哪个对象)调用run方法?

谢谢,
-Abhishek

您的示例没有太大意义,因为锁是在每个实例级别上的,而不是您可能希望使用的每个类级别上的

我想你弄错了一点。线程正在包装执行命令的代码。这些执行通常包含对其他对象的访问。这就是锁定进入游戏的关键所在。每个对象都有一个可以通过线程获得的监视器。但是,一次只能有一个线程获得锁。因此,其他线程排队,只要当前持有者释放对象,就可以访问该对象,只需退出一个同步代码块

我想你可能想做这样的事情:

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();
  }
}

您已经启动了这两个线程,但这取决于它可能执行的JVM线程,因此取决于开始执行的线程,第一个线程将获得锁,第二个线程在第一个线程停止之前不能处于运行状态

但在您的情况下,由于两者都是不同的线程实例,它们并行运行,因为锁是在对象级别获得的。

正式定义 当线程调用同步方法时,它会自动获取该方法对象的内在锁,并在该方法返回时释放它。即使返回是由未捕获的异常引起的,也会发生锁释放


如果希望一次只执行一个线程(重点是什么),那么应该调用一个静态方法,并从run()内部调用该方法,一个类的所有对象只有一个静态方法
t1拥有t1实例的锁。
t2具有t2实例的锁

但是你的例子没有多大意义

也许这个例子可以帮助您:

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());
        }

    }

}
}

输出为:

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();

  }

否,run方法将由两个线程执行。它们是不同的实例和不同的锁。@Hugo我还有一个疑问。线程t1/t2对象只调用start()方法,而不调用run()方法。我认为调度程序决定了run()方法的调用,但实际上是谁调用了run()方法。是t1/t2对象吗?
start()
执行所有引导工作,以生成新线程,甚至调用
run()
方法。您可以在thread的api文档中阅读它。start()方法实际上调用run()方法。这里是api Thread.start()文档中的一句话:“使该线程开始执行;Java虚拟机调用该线程的run方法。”因此,实际上调用run方法的是Java虚拟机。
t1
t2