死锁是指两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若无外力作用,它们都将无法推进下去。此时称系统处于死锁状态,这些永远在互相等待的进程称为死锁进程。
实现死锁的方式有如下几种:
方式一(在synchronized的方法中调用对方对象的方法)
package deadlock;
/**
* Created by lkmc2 on 2018/1/27.
*/
class MyThread1 implements Runnable {
private String objName;
private MyThread1 lockObj; //用来持有对方的对象
public MyThread1(String objName) {
this.objName = objName;
}
public void setLockObj(MyThread1 lockObj) {
this.lockObj = lockObj;
}
public synchronized void intoB() {
String currentThread = Thread.currentThread().getName();
System.out.printf("线程%s进入intoB,objName=%s\n", currentThread, objName);
try {
Thread.sleep(2000);
} catch (InterruptedException x) {
}
System.out.printf("线程%s尝试进入intoA,objName=%s\n", currentThread, objName);
lockObj.intoA();
System.out.printf("线程%s离开intoB(),objName=%s\n", currentThread, objName);
}
public synchronized void intoA() {
String currentThread = Thread.currentThread().getName();
System.out.printf("线程%s进入intoA,objName=%s\n", currentThread, objName);
try {
Thread.sleep(500);
} catch (InterruptedException x) {
}
System.out.printf("线程%s尝试进入intoB,objName=%s\n", currentThread, objName);
lockObj.intoB();
System.out.printf("线程%s离开intoA(),objName=%s\n", currentThread, objName);
}
@Override
public void run() {
if (objName.equals("A")) {
intoA();
} else {
intoB();
}
}
}
public class Test1 {
public static void main(String[] args) throws InterruptedException {
final MyThread1 obj1 = new MyThread1("A");
final MyThread1 obj2 = new MyThread1("B");
obj1.setLockObj(obj2); //持有对方的对象
obj2.setLockObj(obj1);
Thread threadA = new Thread(obj1, "threadA");
threadA.start();
Thread.sleep(200);
Thread threadB = new Thread(obj2, "threadB");
threadB.start();
}
}
方式1运行结果.png
方式二(在synchronized代码块中锁定不同的对象)
package deadlock;
/**
* Created by lkmc2 on 2018/1/27.
*/
class MyThread2 implements Runnable {
private final String[] lock = {"A", "B"};
private void intoA(String threadName, int index) {
System.out.println("线程" + threadName + "尝试进入intoA");
synchronized (lock[index]) {
System.out.println("线程" + threadName + "进入intoA");
sleep(200);
intoB(threadName, 1);
}
}
private void intoB(String threadName, int index) {
System.out.println("线程" + threadName + "尝试进入intoB");
synchronized (lock[index]) {
System.out.println("线程" + threadName + "进入intoB");
sleep(200);
intoA(threadName, 0);
}
}
@Override
public void run() {
String threadName = Thread.currentThread().getName();
if ("threadA".equals(threadName)) {
intoA(threadName, 0);
} else {
intoB(threadName, 1);
}
}
public void sleep(int time) {
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class Test2 {
public static void main(String[] args) throws InterruptedException {
MyThread2 thread1 = new MyThread2();
new Thread(thread1, "threadA").start();
Thread.sleep(5);
new Thread(thread1, "threadB").start();
}
}
方式2运行结果.png
方式三(嵌套两层synchronized锁并相互锁定所需的对象)
package deadlock;
/**
* Created by lkmc2 on 2018/1/27.
*/
class LockA implements Runnable {
@Override
public void run() {
System.out.println("LockA开始执行……");
while (true) {
synchronized (Test3.obj1) {
System.out.println("LockA锁住obj1……");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (Test3.obj2) {
System.out.println("LockA锁住obj2……");
}
System.out.println("LockA释放obj2……");
}
System.out.println("LockA释放obj1……");
}
}
}
class LockB implements Runnable {
@Override
public void run() {
System.out.println("LockB开始执行……");
while (true) {
synchronized (Test3.obj2) {
System.out.println("LockB锁住obj1……");
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (Test3.obj1) {
System.out.println("LockB锁住obj2……");
}
System.out.println("LockB释放obj2……");
}
System.out.println("LockB释放obj1……");
}
}
}
public class Test3 {
public static final byte[] obj1 = new byte[0];
public static final byte[] obj2 = new byte[0];
public static void main(String[] args) {
LockA lockA = new LockA();
LockB lockB = new LockB();
new Thread(lockA).start();
new Thread(lockB).start();
}
}
方式3运行结果.png
网友评论