Java 如果代码运行时间足够长,它会死锁吗?

Java 如果代码运行时间足够长,它会死锁吗?,java,multithreading,deadlock,Java,Multithreading,Deadlock,这个人为设计的项目最终会陷入僵局,不是吗 在共享对象中同步两个方法。这两个线程最终会发现自己在其中一个方法中,并试图调用另一个方法。我想 package main; import java.util.ArrayList; import java.util.List; import myThread.MyThread; import sharedObject.SharedObject; import uncooperativeThread.UncooperativeThread; publi

这个人为设计的项目最终会陷入僵局,不是吗

在共享对象中同步两个方法。这两个线程最终会发现自己在其中一个方法中,并试图调用另一个方法。我想

package main;

import java.util.ArrayList;
import java.util.List;

import myThread.MyThread;
import sharedObject.SharedObject;
import uncooperativeThread.UncooperativeThread;

public class Main {

    public static void main(String[] args) {
        competingThreads();
        //uncooperativeThreads();
        
    }
    private static void competingThreads() {
        List<MyThread> myThreads = new ArrayList<MyThread>();
        SharedObject sharedObject = new SharedObject();
        int threads = 2;
        for (int i = 0; i < threads; i++) {
            myThreads.add(new MyThread(i, sharedObject));
        }

        for (MyThread t : myThreads) {
            t.start();
        }

        for (MyThread t : myThreads) {
            try {t.join();} catch (Exception ex) {}
        }
    }
    /**
     * We will try to call SharedObject.methodC from two threads. The first one will get in, the second will have to wait.
     */
    private static void uncooperativeThreads() {
        SharedObject sharedObject = new SharedObject();
        UncooperativeThread t1 = new UncooperativeThread(1, sharedObject);
        UncooperativeThread t2 = new UncooperativeThread(2, sharedObject);
        
        t1.start();
        t2.start();
        
        try {t1.join();} catch (Exception ex) {}
        try {t2.join();} catch (Exception ex) {}
    }
}


package myThread;

import sharedObject.SharedObject;

public class MyThread extends Thread {
    private int id;
    SharedObject sharedObject;
    
    public MyThread(int id, SharedObject sharedObject) {
        this.id = id;
        this.sharedObject = sharedObject;   // Reference
        
    }
    public void run() {
        doStuff();
    }
    private void doStuff() {
        int counter = 0;
        while (true) {
            System.out.println(++counter);
            if (id % 2 == 1) {
                sharedObject.methodA(id);
            } else {
                sharedObject.methodB(id);
            }
        }       
    }
}

package sharedObject;

import java.util.Random;

public class SharedObject {
    public synchronized void methodA(int id) {
        //System.out.println("methodA(): Thread " + id);
        try {Thread.sleep((new Random()).nextInt(1000));} catch(Exception ex) {}
        if (id == 0) {return;}
        // What I want is for one thread to try to call methodB() while the *other* thread is in methodB() trying to call methodA(). 
        methodB(id);
    }
    
    public synchronized void methodB(int id) {
        //System.out.println("methodB(): Thread " + id);
        try {Thread.sleep((new Random()).nextInt(1000));} catch(Exception ex) {}
        if (id == 1) {return;}
        methodA(id);
    }
}
packagemain;
导入java.util.ArrayList;
导入java.util.List;
导入myThread.myThread;
导入sharedObject.sharedObject;
导入不合作线程。不合作线程;
公共班机{
公共静态void main(字符串[]args){
竞争线程();
//不合作线程();
}
私有静态void competingThreads(){
List myThreads=new ArrayList();
SharedObject SharedObject=新的SharedObject();
int线程=2;
对于(int i=0;i
//我想要的是一个线程尝试调用methodB(),而另一个线程在methodB()中尝试调用methodA()

这不是僵局。试图调用
methodB()
的线程将被迫等待,直到另一个线程通过调用
methodB()
返回来释放锁

要获得典型的死锁,需要有两个锁。您的程序只有一个锁—属于您的程序创建的
SharedObject
的单个实例的固有锁

典型的死锁是当一个线程已经获取了锁A并等待获取锁B,而另一个线程已经获取了锁B,并且它正在等待获取锁A。在这种情况下,在另一个线程释放其锁之前,任何一个线程都不能前进。但是,这两个线程都不会释放其锁,因为这两个线程都无法取得进展


你需要两把锁。您有两个方法(
methodA()
methodB()
),但它们都锁定同一个锁。

。无论哪个线程拥有锁,它都将前进,直到释放锁为止。然后,无论哪个线程获得锁,都将再次向前推进,直到释放它。谢谢您的解释。我拼凑了一个简单得多的例子,两组嵌套的同步块使用了两个不同的锁:每个嵌套集中的锁都是反向的。然后我运行了两个线程,在不到多次迭代之后,它就死锁了。