如果这段代码运行时间足够长,它会死锁吗?
Will this code deadlock if it runs long enough?
这个人为的项目最终会陷入僵局,不是吗?
两个方法在共享对象中同步。这两个线程最终会发现自己在其中一个方法中并试图调用另一个方法。我觉得。
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);
}
}
// What I want is for one thread to try to call methodB() while the other thread is in methodB() trying to call methodA().
这不是僵局。试图调用 methodB()
的线程将被迫等待,直到另一个线程通过从 its methodB()
调用返回释放锁。
要获得经典死锁,您需要有两个锁。您的程序只有一个锁 - 属于您的程序创建的 SharedObject
的单个实例的内部锁。
一个经典的死锁是当一个线程已经获得了锁A,正在等待获得锁B,而另一个线程已经获得了锁B,正在等待获得锁A。在这种情况下,两个线程都无法取得进展直到另一个线程释放它的锁。但是,两个线程都不会释放它的锁,因为两个线程都无法取得进展。
你需要两把锁。你有两个方法(methodA()
和methodB()
),但它们都锁定了同一个锁。
这个人为的项目最终会陷入僵局,不是吗?
两个方法在共享对象中同步。这两个线程最终会发现自己在其中一个方法中并试图调用另一个方法。我觉得。
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);
}
}
// What I want is for one thread to try to call methodB() while the other thread is in methodB() trying to call methodA().
这不是僵局。试图调用 methodB()
的线程将被迫等待,直到另一个线程通过从 its methodB()
调用返回释放锁。
要获得经典死锁,您需要有两个锁。您的程序只有一个锁 - 属于您的程序创建的 SharedObject
的单个实例的内部锁。
一个经典的死锁是当一个线程已经获得了锁A,正在等待获得锁B,而另一个线程已经获得了锁B,正在等待获得锁A。在这种情况下,两个线程都无法取得进展直到另一个线程释放它的锁。但是,两个线程都不会释放它的锁,因为两个线程都无法取得进展。
你需要两把锁。你有两个方法(methodA()
和methodB()
),但它们都锁定了同一个锁。