Java多线程同步(对象)
我有3节课,如下所示。我使用了Java多线程同步(对象),java,multithreading,deadlock,Java,Multithreading,Deadlock,我有3节课,如下所示。我使用了synchronized(b)因此,一个对象获得了b对象上的锁,并且在A中的foo方法完成工作之前,不会调用b中的任何方法 但是,这似乎不起作用(见最后的输出)。实际上,racethread能够调用对象b上的方法 注意:您可以创建一个简单的java项目,并在一个文件中添加以下代码以尝试执行 包com.threads.main.deadlock class A { void foo(B b) { synchronized (b) { // Tr
synchronized(b)
因此,一个对象获得了b对象上的锁,并且在A
中的foo
方法完成工作之前,不会调用b中的任何方法
但是,这似乎不起作用(见最后的输出)。实际上,racethread
能够调用对象b上的方法
注意:您可以创建一个简单的java项目,并在一个文件中添加以下代码以尝试执行
包com.threads.main.deadlock
class A {
void foo(B b) {
synchronized (b) { // Trying to get lock on b here
String name = Thread.currentThread().getName();
System.out.println(name + " entered A.foo");
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("A Interrupted");
}
System.out.println(name + " trying to call B.last()");
b.last();
}
}
synchronized void last() {
System.out.println("Inside A.last");
}
}
class B {
void bar(A a) {
synchronized (a) {
String name = Thread.currentThread().getName();
System.out.println(name + " entered B.bar");
try {
Thread.sleep(1000);
} catch (Exception e) {
System.out.println("B Interrupted");
}
System.out.println(name + " trying to call A.last()");
a.last();
}
}
synchronized void last() {
System.out.println("Inside B.last");
}
}
public class Deadlock implements Runnable {
A a = new A();
B b = new B();
Deadlock() {
Thread.currentThread().setName("MainThread");
Thread t = new Thread(this, "RacingThread");
t.start();
new Thread(new Dum(a)).start();
a.foo(b); // get lock on a in this thread.
System.out.println("Back in main thread");
}
public void run() {
b.bar(a); // get lock on b in other thread.
System.out.println("Back in other thread");
}
public static void main(String args[]) {
new Deadlock();
}
}
class Dum implements Runnable {
A a = null;
public Dum(A a) {
this.a = a;
}
@Override
public void run() {
int i =0;
while (i++ < 5) {
System.out.println("Trying a.last .. dum");
a.last();
}
}
}
A线程和B线程在其方法中使用不同的对象进行同步 那么你的假设呢 对象获得B对象上的锁,而B中没有任何方法 将被调用,直到A中的foo方法完成工作 这是错误的。当A.foo运行时,它使用B的实例进行同步。但是,这只会阻止B.last的并行运行,因为B.foo在a上有一个同步块。但是,当a.foo尝试调用B.last时,它不会导致任何阻塞,因为a.foo已经在B的监视器中 如果您有这样的方法:
synchronized void last() {
}
这基本上相当于:
void last() {
synchronized(this){ //so in case of Class B it means: this = the B instance
}
}
我建议您命名所有线程,并将Thread.currentThread().getName()添加到每个系统中,这样您就会更好地理解它。您在这里的期望值真的不清楚;没有什么会导致死锁。可能是另一种误解,即两个线程需要在同一个对象监视器上同步才能同步,并且无法“锁定对象”。@Kayaman,能否请您在“两个线程需要在同一个对象监视器上同步才能同步”上进行eloborate?能否请您修改类并显示它。这很难理解,因为我是多线程新手。另外,下一个点,当我添加同步(对象)时,对象将被刚刚进入对象监视器的线程锁定;在线程释放监视器之前,锁定对象中的任何方法都不会被其他线程访问?@BrianRoach我希望foo()对象在保持B上的方法锁定的同时完成执行,在我执行完foo()之后,其他线程可以调用对象B上的方法。但是,根据我在控制台中打印的输出语句,我无法锁定对象B。您描述的正是发生的情况。您在A的实例上进行了同步,休眠了一秒钟,名为
A.last()
,然后释放。当这种情况发生时,您的Dum
runnable在a.last()上阻塞
void last() {
synchronized(this){ //so in case of Class B it means: this = the B instance
}
}