Java 实现死锁条件
我试图实现死锁条件,但不知何故,我无法让它工作。线程Thread1和Thread2都进入run函数,但根据谁先进入run,只有一个线程进入Sub/Sum。示例:如果Thread2先输入run,它将调用sub(),Thread1从不调用sum()。我还添加了睡眠时间,以便Thread2在调用sum()之前睡眠,Thread1有足够的时间输入sum(),但Thread1从未进入Java 实现死锁条件,java,multithreading,Java,Multithreading,我试图实现死锁条件,但不知何故,我无法让它工作。线程Thread1和Thread2都进入run函数,但根据谁先进入run,只有一个线程进入Sub/Sum。示例:如果Thread2先输入run,它将调用sub(),Thread1从不调用sum()。我还添加了睡眠时间,以便Thread2在调用sum()之前睡眠,Thread1有足够的时间输入sum(),但Thread1从未进入 public class ExploringThreads { public static voi
public class ExploringThreads {
public static void main(String[] args) {
// TODO Auto-generated method stub
threadexample a1 = new threadexample();
Thread t1 = new Thread(a1, "Thread1");
Thread t2 = new Thread(a1,"Thread2");
t1.start();
t2.start();
}
}
class threadexample implements Runnable{
public int a = 10;
public void run(){
if(Thread.currentThread().getName().equals("Thread1"))
sum();
else if(Thread.currentThread().getName().equals("Thread2"))
sub();
}
public synchronized void sum()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"In Sum");
sub();
}
public synchronized void sub()
{
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"In Sub");
sum();
}
}
这不是死锁的原因。实际上,这段代码看起来相当安全:-)一次只有一个线程输入sum/sub,因为您使用的是同步的,它在“this”上同步。只有一个“this”,因此两个线程都尝试获取相同的锁 死锁发生,例如,当Thread1有一个锁,Thread2有第二个锁,然后Thread1希望在保持Thread2锁的同时获得Thread2锁,Thread2希望在保持Thread1锁的同时获得Thread1锁 你能做的是: a) 在“threadexample”类中添加2个用于锁定的对象(顺便说一句,按照惯例,类应以大写开头): b) 在两个sum/sub方法中删除“synchronized”关键字,而是在每个方法中使用synchronized(){}块。Sum将被同步(sumLock){/*Sum的主体在这里/},sub将被同步(subLock){/sub的主体在这里*/} 在这种情况下,Thread1将进入sum(),获取sumLock并等待。Thread2将进入sub(),获取subLock()并等待。Thread1会醒来,进入sub()并尝试获取subLock,但它被Thread2持有,所以它会等待Thread2释放它。此时,Thread2醒来,进入sum()并尝试获取Thread1持有的sumLock,因此Thread2等待Thread1释放它 这两个线程都不会前进,因为它们中的每一个都在等待另一个线程——这是一个死锁
@编辑:是的,您只有一个“threadexample”实例,Thread1和Thread2都在争夺锁,但当其中一个获得锁时,它将在执行sum/sub或sub/sum后释放锁。例如,假设Thread1是第一个并开始执行sum()。它有锁。在这种情况下,Thread2将不会进入sub(),因为它受到与Thread1相同的锁的保护。Thread1将执行sum(),然后是sub(),然后它将释放锁-->Thread2将进入sub()等等。如果确实要创建一个人工死锁,请尝试以下操作:
Thread1
和Thread2
是要访问同一文件的两个线程
Thread1
启动,请求锁定File1.docx
并睡眠2分钟李>
Thread2
启动,并对File2.docx
进行独占锁定,现在希望访问File1.docx
李>
Thread1
唤醒,现在想要访问File2.docx
,该文件由Thread2
简单?=) 这是“行动中的死锁”的一个工作示例。基本上,您需要做的(以及在现实世界中通常发生的情况)是以相反的顺序锁定对象:一个线程中的第一个、第二个和另一个线程中的第一个、第二个:
package stackoverflow;
public class Deadlock {
final static String a = new String("A");
final static String b = new String("B");
public static void main(String[] args) {
final Thread abLock = new Thread() {
@Override
public void run() {
lock(a, b);
}
};
final Thread baLock = new Thread() {
@Override
public void run() {
lock(b, a);
}
};
abLock.start();
baLock.start();
}
static void lock(String first, String second) {
synchronized (first) {
System.out.println(first);
sleep();
synchronized (second) {
System.out.println(second);
}
}
}
static void sleep() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
对不起,我不明白。这可能是因为我不熟悉线程。根据我的理解,我只制作了threadexample类的一个对象。Thread1和Thread2正在竞争获得sum()和sub()的锁。您的示例不正确<只要
线程
未释放其锁,则代码>线程2将被阻止,但这不是死锁。当两个(或多个)线程被永久阻止时,就会发生死锁情况,因为每个线程都被阻止,等待获取另一个线程拥有的独占资源。
package stackoverflow;
public class Deadlock {
final static String a = new String("A");
final static String b = new String("B");
public static void main(String[] args) {
final Thread abLock = new Thread() {
@Override
public void run() {
lock(a, b);
}
};
final Thread baLock = new Thread() {
@Override
public void run() {
lock(b, a);
}
};
abLock.start();
baLock.start();
}
static void lock(String first, String second) {
synchronized (first) {
System.out.println(first);
sleep();
synchronized (second) {
System.out.println(second);
}
}
}
static void sleep() {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}