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