【发布时间】:2017-12-29 18:58:36
【问题描述】:
(我刚刚开始发帖,所以很有可能我会错)
如果同一类的两个线程,其中一个变量进入同步方法,它们切换其中一个变量,并尝试使用切换变量访问另一个同步方法。会发生死锁吗?为什么?
我正在谈论的一个例子:类:
public class Person extends Thread{
public Hand leftHand;
public Hand rightHand;
public String name;
public Person friend;
public Person(Hand a, Hand b, String name, Person f){
this.leftHand = a;
this.rightHand = b;
this.name = name;
this.friend = f;
}
public void switchHands(){
if(leftHand.color.equals(rightHand.color)){
Hand temp = this.rightHand;
this.rightHand = friend.rightHand;
friend.rightHand = temp;
}
}
public void run(){
synchronized (leftHand){
System.out.println(this.name + " locked with " + this.leftHand);
switchHands();
synchronized (rightHand){
System.out.println(this.name + " locked with " + this.rightHand);
}
}
}
public static class Hand{
String color;
public Hand(String c){ this.color = c; }
}
}
主要是:
public static void main(String[] args){
Hand whiteHand = new Hand("white");
Hand blackHand = new Hand("black");
Person one = new Person(whiteHand, whiteHand, "one", null);
Person second = new Person(blackHand, blackHand, "second", null);
one.friend = second;
second.friend = one;
one.start();
second.start()
}
如您所见,两个线程(一个和两个)被锁定在 synchronized (leftHand) 中,然后其中一个线程至少换手(右手),然后 - 我们尝试访问 synchronized (rightHand),并且可能发生了死锁。
逻辑我能理解,但是当我换手的时候,直觉上我想我只是复制另一只手的内容,但是我不明白为什么会出现死锁。
P.S 我觉得我的标题不够准确,所以欢迎编辑。
【问题讨论】:
-
此代码目前甚至无法编译。请修复它,以便清楚您在说什么。
-
已修复。如果你运行它几次,它最终会进入一个块。真正的类有函数在路上,所以总是发生死锁
-
Re,“同一类的两个线程。”线程不属于任何类。线程是执行代码的东西。线程开始执行的
run()方法必须属于某个类,因为在Java 中,每个 方法都必须属于某个类;但这并没有在线程和类之间建立任何特殊关系。线程就是执行你给它的任何对象的run()方法的东西。 -
Re,“其中一个变量进入了同步方法。”这没有任何意义。变量不会“进入”(或退出)方法或任何其他地方。静态变量保留在声明它们的类中,实例变量保留在创建它们的对象中,而局部变量保留在创建它们的函数激活中。变量不是可以移动的东西。但有时我们会谈论将值从一个变量移动到另一个变量。
-
另外,线程可以进入(即“调用”)或退出(即“返回”)方法。
标签: java multithreading synchronization deadlock synchronized