
github:
该代码全部由GitHub学生托管java多线程死锁,需要他们自己下载该代码
如果设计不正确,多线程可能会死锁. 当两个或多个线程同事希望获得共享资源的锁时,每个线程必须等待其他线程将它们分开. 要释放锁才能继续运行,这是死锁. 僵局必须存在以下几点

例如线程1
synchronized(A){
//Thread1 执行到这里
synchronized(B){
...
}
}
线程2

synchronized(B){
//Thread2 执行到这里
synchronized(A){
...
}
}
以上情况是一个僵局. 如果两个线程陷入僵局,则可能更容易发现问题. 更复杂的是,有多个线程,例如线程n各自拥有锁n,然后线程1到线程n-1要求获取锁n + 1java多线程死锁,而线程n要求获取锁1,这也可能导致死锁,并且更难检测.
我们想看个例子

public class Demo1 {
public static void main(String[] args) {
Object bigGate = new Object();
Object smallGate = new Object();
new Thread(new Runnable() {
@Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (bigGate){
System.out.println(name + ":我把大门给锁了...然后我休息一下...");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + ":我现在要进入小门.....");
synchronized (smallGate){
System.out.println(name + ":我永远都进不来啊.....");
}
}
}
},"小明").start();
new Thread(new Runnable() {
@Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (smallGate){
System.out.println(name + ":我把小门给锁了...然后我休息一下...");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + ":我现在要进入大门.....");
synchronized (bigGate){
System.out.println(name + ":我永远都进不来啊.....");
}
}
}
},"小红").start();
}
}
运行结果
小明我把大门给锁了...然后我休息一下...
小红我把小门给锁了...然后我休息一下...
小明:我现在要进入小门.....
小红:我现在要进入大门.....
//然后程序到这里就一直不动了..... public class Demo2 {
public static void main(String[] args) {
Object bigGate = new Object();
Object smallGate = new Object();
new Thread(new Runnable() {
@Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (bigGate){
System.out.println(name + ":我把大门给锁了...然后我休息一下...");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + ":我现在要进入小门.....");
synchronized (smallGate){
System.out.println(name + ":我终于进来了.....");
}
}
}
},"小明").start();
new Thread(new Runnable() {
@Override
public void run() {
String name = Thread.currentThread().getName();
synchronized (bigGate){
System.out.println(name + ":我把大门给锁了...然后我休息一下...");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + ":我现在要进入小门.....");
synchronized (smallGate){
System.out.println(name + ":我终于进来了.....");
}
}
}
},"小红").start();
}
}

运行结果:
小明:我把大门给锁了...然后我休息一下...
小明:我现在要进入小门.....
小明:我终于进来了.....
小红:我把大门给锁了...然后我休息一下...
小红:我现在要进入小门.....
小红:我终于进来了..... public class Demo3 {
public static void main(String[] args) {
Lock bigGate = new ReentrantLock();
Lock smallGate = new ReentrantLock();
Random random = new Random();
new Thread(new Runnable() {
@Override
public void run() {
String name = Thread.currentThread().getName();
bigGate.lock();
try {
System.out.println(name + ":我把大门给锁了...然后我休息一下...");
Thread.sleep(100);
System.out.println(name + ":我现在要进入小门.....");
if(smallGate.tryLock(random.nextInt(500), TimeUnit.MILLISECONDS)){
try {
System.out.println(name + ":我终于进来了.....");
}finally {
smallGate.unlock();
}
}else{
System.out.println(name + ":我进不去小门,算了,不进了...");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bigGate.unlock();
}
}
},"小明").start();
new Thread(new Runnable() {
@Override
public void run() {
String name = Thread.currentThread().getName();
smallGate.lock();
try {
System.out.println(name + ":我把小门给锁了...然后我休息一下...");
Thread.sleep(100);
System.out.println(name + ":我现在要进入大门.....");
if(bigGate.tryLock(random.nextInt(500), TimeUnit.MILLISECONDS)){
try {
System.out.println(name + ":我终于进来了.....");
}finally {
bigGate.unlock();
}
}else{
System.out.println(name + ":我进不去大门,算了,不进了...");
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
smallGate.unlock();
}
}
},"小红").start();
}
}
运行结果:
小明:我把大门给锁了...然后我休息一下...
小红:我把小门给锁了...然后我休息一下...
小明:我现在要进入小门.....
小红:我现在要进入大门.....
小红:我进不去大门,算了,不进了...
小明:我终于进来了.....
这也保证不会发生死锁.
如果您认为我的文章可以接受,请在有钱的情况下写一个钱币字段,如果没有钱就给我一个个人字段(帮我喜欢或推荐)
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-158715-1.html