Java 这是线程死锁吗
我想故意执行/测试java线程死锁状态,因此我编写了以下示例代码:Java 这是线程死锁吗,java,multithreading,deadlock,Java,Multithreading,Deadlock,我想故意执行/测试java线程死锁状态,因此我编写了以下示例代码: public class TestDeadLock extends Thread{ private Integer a=new Integer(9); public void run(){ if(Thread.currentThread().getName().equals("t1")){ XXXX(); } else{
public class TestDeadLock extends Thread{
private Integer a=new Integer(9);
public void run(){
if(Thread.currentThread().getName().equals("t1")){
XXXX();
}
else{
ZZZZ();
}
}
public void XXXX(){
System.out.println("inside XXXX");
synchronized(a){
a++;
ZZZZ();
}
System.out.println("xxxxxxxxxxxxxxxxxxx");
//ZZZZ();
}
public synchronized void ZZZZ(){
System.out.println("inside ZZZZ");
synchronized(a){
a--;
XXXX();
}
System.out.println("zzzzzzzzzzzzzzzzzzzzz");
}
public static void main(String[] args) throws InterruptedException {
TestDeadLock tdl=new TestDeadLock();
Thread t1=new Thread(tdl);
Thread t2=new Thread(tdl);
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
Thread.sleep(1000);
System.out.println("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="+tdl.a);
}
}
输出结果如下:
XXXX内
内ZZZZ
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=10
输出未退出。
我想知道,这是由于线程达到了死锁状态吗?遇到死锁是一个正确的例子吗?如果我错了,建议或纠正我。不,你没有遇到死锁。您遇到了一个
堆栈溢出错误
,因为您正在运行一个无限循环
请注意,您的方法
public synchronized void ZZZZ() {
System.out.println("inside ZZZZ");
XXXX(); // run-time exception
}
相当于
public void ZZZZ() {
synchronized(this) {
System.out.println("inside ZZZZ");
XXXX(); // run-time exception
}
}
您正在处理两个不同的实例,因此不会导致死锁。
线程1锁定
t1
,线程2锁定t2
不,您没有遇到死锁。您遇到了一个堆栈溢出错误
,因为您正在运行一个无限循环
请注意,您的方法
public synchronized void ZZZZ() {
System.out.println("inside ZZZZ");
XXXX(); // run-time exception
}
相当于
public void ZZZZ() {
synchronized(this) {
System.out.println("inside ZZZZ");
XXXX(); // run-time exception
}
}
您正在处理两个不同的实例,因此不会导致死锁。
线程1锁定t1
,线程2锁定t2
尝试以下示例:
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 2...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 1...");
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
这准确地显示了达到死锁的线程
以下是解决方案:
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
来源:试试这个例子:
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 2...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 1...");
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
这准确地显示了达到死锁的线程
以下是解决方案:
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
来源:您的ZZZZ()方法包含对XXXX()方法的调用,反之亦然。
因此,您创建了一个永无止境的调用链:ZZZZ()->XXXX()->zzzzz()->XXXX()->等等
最终,堆栈将因推送到堆栈上的所有嵌套方法调用而变得太大。因此,您得到的异常。您的ZZZZ()方法包含对XXXX()方法的调用,反之亦然。
因此,您创建了一个永无止境的调用链:ZZZZ()->XXXX()->zzzzz()->XXXX()->等等
最终,堆栈将因推送到堆栈上的所有嵌套方法调用而变得太大。因此,您将得到例外情况。Jase Pellerin给出的示例是死锁的一个很好的示例,但它有一个错误(抱歉,Jase Pellerin,我相信您是非故意这样做的)。在这里,两种方法都试图先获得
Lock1
,然后再获得Lock2
。我想应该是另一种方式
Thread1{
synchronized (Lock1) {
synchronized (Lock2) {}
}
}
Thread2{
synchronized (Lock2) {
synchronized (Lock1) {}
}
}
Jase Pellerin给出的例子是死锁的一个很好的例子,但它有一个错误(对不起Jase Pellerin,我相信你是非故意的)。在这里,两种方法都试图先获得
Lock1
,然后再获得Lock2
。我想应该是另一种方式
Thread1{
synchronized (Lock1) {
synchronized (Lock2) {}
}
}
Thread2{
synchronized (Lock2) {
synchronized (Lock1) {}
}
}
您能否将抛出的异常添加到问题中(在代码块中)?否则,几乎不可能确定错误是什么。不,这是一个竞赛条件。不要将你的问题编辑为完全不同的问题。如果您有一个新问题,请打开一个新问题。是否可以将引发的异常添加到问题中(在代码块中)?否则,几乎不可能确定错误是什么。不,这是一个竞赛条件。不要将你的问题编辑为完全不同的问题。如果你有一个新问题,打开一个新问题。让我们让编码的世界少一点混乱。我希望你不介意。我从您帐户的
关于面板;)中复制粘贴了它让我们让编码的世界少一点混乱。我希望你不介意。我从您帐户的关于面板;)中复制粘贴了它一个线程当时占用ZZZZ an,在占用XXXX methode之前,另一个线程可能占用XXXX methode,然后在发生任何堆栈溢出错误之前,两个线程都会无限期地等待对方。一个线程占用自身的锁(t1
),另一个线程占用自身的锁(t2
),另一个线程可以获取zzzz,因此将锁定它,而另一个线程将等待zzzz,而另一个线程正在等待xxxx。请稍微考虑一下。两个线程都是类的独立实例TestDeadLock
。名为t1
的线程将始终调用XXXX()
并获取必要的锁。名为t2
的线程将始终在实例t2
(尚未锁定)上调用ZZZZ()
,并获取锁。试试看!天哪,我没有很好地处理代码,两个线程都是th类的独立实例,很抱歉,你是对的,我将删除答案以避免误解一个线程当时占用了ZZZZ an,在占用XXXX methode之前,另一个线程可能占用XXXX methode,然后在发生任何stackoverflow错误之前,这两个线程会无限期地等待对方。对不起,这是不正确的。一个线程占用自身的锁(t1
),另一个线程占用自身的锁(t2
),另一个线程可以获取zzzz,因此将锁定它,而另一个线程将等待zzzz,而另一个线程正在等待xxxx。请稍微考虑一下。两个线程都是类的独立实例TestDeadLock
。名为t1
的线程将始终调用XXXX()
并获取必要的锁。名为t2
的线程将始终在实例t2
(尚未锁定)上调用ZZZZ()
,并获取锁。试试看!天哪,我没有很好地处理代码,两个线程都是th类的独立实例,很抱歉你是对的,我将删除答案,以免引起误解