试图在两个线程之间创建死锁
Trying to create a deadlock between two threads
通过访问线程中的打印方法在两个线程之间创建死锁。我使用了循环屏障,以便两个线程同时启动。如果我是正确的,我的打印方法没有花费时间,因此它被两个线程共享并且不会导致死锁。
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class TWOTHREADDEADLOCLK {
static int b =0;
synchronized static void print()
{
System.out.println(Thread.currentThread().getName() + " " + b);
}
synchronized static int getb()
{
print();
return b;
}
synchronized static void updateb()
{
print();
b=b+10;
}
public static void main(String[] args) {
final CyclicBarrier bar = new CyclicBarrier(2);
Thread thread1 = new Thread(new Runnable(){
@Override
public void run()
{
try {
bar.await();
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch ( BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
while(true)
print();
}
});
Thread thread2 = new Thread(new Runnable(){
@Override
public void run()
{try {
bar.await();
} catch (InterruptedException | BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
while(true)
getb();
}
});
thread1.start();
thread2.start();
}
}
你不能用一个屏障来制造死锁。死锁背后的想法是有(至少)两个线程,每个线程持有不同的锁并试图锁定另一个线程。例如,考虑这个简单的例子:
public class TwoLockRunnable implements Runnable {
private Lock lockInConstructor;
private Lock lockInRuntime;
public TwoLockThread(Lock lockInConstructor, Lock lockInRuntime) {
this.lockInConstructor = lockInConstructor;
this.lockInRuntime = lockInRuntime;
this.lockInConstructor.lock();
}
@Override
public void run() {
lockInRuntime.lock();
System.out.println("After the lock in run()");
}
public static void main(String[] args) {
Lock lock1 = new ReentrantLock();
Lock lock2 = new ReentrantLock();
TwoLockRunnable runnable1 = new TwoLockThread(lock1, lock2);
TwoLockRunnable runnable2 = new TwoLockThread(lock2, lock1);
new Thread(runnable1).start();
new Thread(runnable2).start();
}
}
第一个线程在其构造函数中锁定 lock1
,第二个线程在其构造函数中锁定 lock2
。然后第一个线程在 运行 时尝试锁定 lock2
- 但它不能,因为另一个线程持有锁。类似地,第二个线程在 运行 时尝试锁定 lock1
,但由于同样的原因而失败。因此,您遇到了死锁,消息 "After the lock in run()"
永远不会被打印出来。
就像 Mureinik 的一样,这是 'synchronized' 演示:
public class DeadLockAATest {
static void methodA(DeadLockAATest d1, DeadLockAATest d2) {
synchronized (d1) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (d2) {
System.out.println("\t\t\tmethodA:" + Thread.currentThread().getName());
}
}
}
public static void main(String[] args) {
DeadLockAATest d1 = new DeadLockAATest(), d2 = new DeadLockAATest();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("t1-start:" + Thread.currentThread().getName());
methodA(d1, d2);
System.out.println("t1-end:" + Thread.currentThread().getName());
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("t2-start:" + Thread.currentThread().getName());
methodA(d2, d1);
System.out.println("t2-end:" + Thread.currentThread().getName());
}
});
t1.start();
t2.start();
System.out.println("deadlock...");
}
}
死锁输出(只有一个条件,可能t2先开始):
t1-start:Thread-0
deadlock...
t2-start:Thread-1
你可以替换
methodA(d2, d1);
到
methodA(d1, d2);
这将输出:
t1-start:Thread-0
t2-start:Thread-1
deadlock...
methodA:Thread-0
t1-end:Thread-0
methodA:Thread-1
t2-end:Thread-1
这不是死锁,希望对你有所帮助。
通过访问线程中的打印方法在两个线程之间创建死锁。我使用了循环屏障,以便两个线程同时启动。如果我是正确的,我的打印方法没有花费时间,因此它被两个线程共享并且不会导致死锁。
import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
public class TWOTHREADDEADLOCLK {
static int b =0;
synchronized static void print()
{
System.out.println(Thread.currentThread().getName() + " " + b);
}
synchronized static int getb()
{
print();
return b;
}
synchronized static void updateb()
{
print();
b=b+10;
}
public static void main(String[] args) {
final CyclicBarrier bar = new CyclicBarrier(2);
Thread thread1 = new Thread(new Runnable(){
@Override
public void run()
{
try {
bar.await();
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch ( BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
while(true)
print();
}
});
Thread thread2 = new Thread(new Runnable(){
@Override
public void run()
{try {
bar.await();
} catch (InterruptedException | BrokenBarrierException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
while(true)
getb();
}
});
thread1.start();
thread2.start();
}
}
你不能用一个屏障来制造死锁。死锁背后的想法是有(至少)两个线程,每个线程持有不同的锁并试图锁定另一个线程。例如,考虑这个简单的例子:
public class TwoLockRunnable implements Runnable {
private Lock lockInConstructor;
private Lock lockInRuntime;
public TwoLockThread(Lock lockInConstructor, Lock lockInRuntime) {
this.lockInConstructor = lockInConstructor;
this.lockInRuntime = lockInRuntime;
this.lockInConstructor.lock();
}
@Override
public void run() {
lockInRuntime.lock();
System.out.println("After the lock in run()");
}
public static void main(String[] args) {
Lock lock1 = new ReentrantLock();
Lock lock2 = new ReentrantLock();
TwoLockRunnable runnable1 = new TwoLockThread(lock1, lock2);
TwoLockRunnable runnable2 = new TwoLockThread(lock2, lock1);
new Thread(runnable1).start();
new Thread(runnable2).start();
}
}
第一个线程在其构造函数中锁定 lock1
,第二个线程在其构造函数中锁定 lock2
。然后第一个线程在 运行 时尝试锁定 lock2
- 但它不能,因为另一个线程持有锁。类似地,第二个线程在 运行 时尝试锁定 lock1
,但由于同样的原因而失败。因此,您遇到了死锁,消息 "After the lock in run()"
永远不会被打印出来。
就像 Mureinik 的一样,这是 'synchronized' 演示:
public class DeadLockAATest {
static void methodA(DeadLockAATest d1, DeadLockAATest d2) {
synchronized (d1) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (d2) {
System.out.println("\t\t\tmethodA:" + Thread.currentThread().getName());
}
}
}
public static void main(String[] args) {
DeadLockAATest d1 = new DeadLockAATest(), d2 = new DeadLockAATest();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("t1-start:" + Thread.currentThread().getName());
methodA(d1, d2);
System.out.println("t1-end:" + Thread.currentThread().getName());
}
});
Thread t2 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("t2-start:" + Thread.currentThread().getName());
methodA(d2, d1);
System.out.println("t2-end:" + Thread.currentThread().getName());
}
});
t1.start();
t2.start();
System.out.println("deadlock...");
}
}
死锁输出(只有一个条件,可能t2先开始):
t1-start:Thread-0
deadlock...
t2-start:Thread-1
你可以替换
methodA(d2, d1);
到
methodA(d1, d2);
这将输出:
t1-start:Thread-0
t2-start:Thread-1
deadlock...
methodA:Thread-0
t1-end:Thread-0
methodA:Thread-1
t2-end:Thread-1
这不是死锁,希望对你有所帮助。