任何人都可以发布最终陷入死锁的java代码吗?
答案 0 :(得分:4)
答案 1 :(得分:2)
答案 2 :(得分:0)
创建两个锁,以及两个同步它们的线程,确保线程1先锁定1,反之亦然。在第一次锁定后,确保线程进入休眠状态一段时间。
public class DeadlockTest {
private static final Object lock1 = new Object();
private static final Object lock2 = new Object();
public static void main(String[] args) {
new Thread("1") {
@Override
public void run() {
synchronized (lock1) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
synchronized (lock2) {
System.out.println("1 got em");
}
}
}
}.start();
new Thread("2") {
@Override
public void run() {
synchronized (lock2) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
synchronized (lock1) {
System.out.println("2 got em");
}
}
}
}.start();
}
}
正如您将看到的那样,“得到它们”的印刷品都不会发生。
答案 3 :(得分:0)
这会导致死锁:
public static void main(String[] args)
{
final Object object1 = new Object();
final Object object2 = new Object();
Thread thread1 = new Thread(
new Runnable()
{
public void run()
{
try
{
//**** Lock on object1 first ****
synchronized(object1)
{
Thread.sleep(1000);
//**** Lock on object2 second ****
synchronized(object2)
{
System.out.println("Should never get here.");
}
}
}
catch (InterruptedException e) {}
}
}
);
Thread thread2 = new Thread(
new Runnable()
{
public void run()
{
try
{
//**** Lock on object2 first ****
synchronized(object2)
{
Thread.sleep(1000);
//**** Lock on object1 second ****
synchronized(object1)
{
System.out.println("Should never get here.");
}
}
}
catch (InterruptedException e) {}
}
}
);
thread1.start();
thread2.start();
}
答案 4 :(得分:0)
将信号量初始化为0将始终导致死锁。 原因可以在enter方法的第一行看到:“while(value == 0){this.wait}”
class Semaphore {
private int value;
public Semaphore (int init){
value = init;
}
synchronized public void exit() {
if (value == 0) this.notify();
++value;
}
synchronized public void enter() throws InterruptedException {
while (value == 0){
this.wait();
}
--value;
}
}
class myThread extends Thread{
Semaphore mutex;
public myThread(Semaphore s){
mutex = s;
}
public void run(){
for(int x=0; x<10;<x++){
mutex.enter();
System.out.println(x);
mutex.exit();
}
}
public static void main(String [ ] args){
Semaphore s = new Semaphore(0);
Thread t1 = new myThread(s);
Thread t2 = new myThread(s);
t1.start();
t2.start()
}
}
答案 5 :(得分:0)
您还可以使用固定大小的线程池进行死锁:
final ExecutorService exec = Executors.newFixedThreadPool(1);
exec.submit(new Runnable() {
public void run() {
Future<?> f = exec.submit(new Runnable() {
public void run() {
}
});
try { f.get(); } catch (Exception ex) { }
}
});
答案 6 :(得分:0)
正如其他答案所说,让两个线程以相反的顺序获得两个锁是导致死锁的一种方法(只要它们在请求第二个锁之前都持有第一个锁)。在下面的代码中,Thread1获得lockA,而线程2获得lockB。一旦他们都获得了第一个锁,他们就会尝试获取另一个线程的锁 - 但是它们会死锁(因为另一个线程仍然有锁)。
不是使用Thread.sleep()来等待第一次锁定,这可能会稍微不可预测并使测试更难/更慢,您可以使用CyclicBarrier来确保两个线程之前获得了第一次锁定他们试图获得他们的第二个(因为他们以相反的顺序获得对方的锁,我们将保证死锁):
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class Deadlocker {
private static class Worker implements Runnable {
private Object firstLock;
private CyclicBarrier firstLockHeld;
private Object secondLock;
public Worker(Object firstLock, CyclicBarrier firstLockHeld, Object secondLock) {
this.firstLock = firstLock;
this.firstLockHeld = firstLockHeld;
this.secondLock = secondLock;
}
@Override
public void run() {
synchronized (firstLock) {
try {
firstLockHeld.await();
} catch (InterruptedException e) {
e.printStackTrace(); // Will not happen unless another thread interrupts
} catch (BrokenBarrierException e) {
e.printStackTrace(); // Will not happen unless another thread interrupts
}
synchronized (secondLock) {
System.err.println("Should never happen!");
}
}
}
}
public static void main(String[] args) {
CyclicBarrier firstLockHeld = new CyclicBarrier(2);
Object lockA = new Object();
Object lockB = new Object();
new Thread(new Worker(lockA, firstLockHeld, lockB)).start();
new Thread(new Worker(lockB, firstLockHeld, lockA)).start();
}
}