模拟死锁

  • Thread.sleep(1000);
  • Thread.yield()

让当前线程睡眠或者让出CPU都是增加了死锁的概率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
public class DeadLock {
private static final Object resource1 = new Object();//资源 1
private static final Object resource2 = new Object();//资源 2

public static void main(String[] args) {
new Thread(() -> {
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource2");
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
}
}
}, "线程 1").start();


new Thread(() -> {
synchronized (resource2) {
System.out.println(Thread.currentThread() + "get resource2");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread() + "waiting get resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread() + "get resource1");
}
}
}, "线程 2").start();
}
}

两个线程交替打印

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class PrintNumber {
public static int num = 1;
public static final Object obj = new Object();
public static void main(String[] args) {
new Thread(() -> {
while (num <= 100){
synchronized (obj){
//操作系统中断可能会被'虚假唤醒',用while循环判断而不是if
//保证另一个线程先打印奇数
while (num % 2 != 0){
try {
obj.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
obj.notify();
System.out.println("偶数线程:"+num++);
try {
obj.wait();
if (num > 100){
obj.notify();
return;
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}, "线程 1").start();

new Thread(() -> {
while (num <= 100){
synchronized (obj){
obj.notify();
System.out.println("奇数线程:"+num++);
try {
obj.wait();
if (num > 100){
obj.notify();
return;
}
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}, "线程 2").start();
}
}

三个线程交替打印

这里用下线程池极加强记忆

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
package com.atzrh.多线程;

import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
* @author zrh
* @version 1.0.0
* @title PrintNumberThree
* @description <三个线程交替打印>
* @create 2026/5/16 16:15
**/
public class PrintNumberThree {
public static ThreadPoolExecutor executor = new ThreadPoolExecutor(3,
3,
1000,
TimeUnit.SECONDS,
new SynchronousQueue<>());
public final static ReentrantLock lock = new ReentrantLock();
public final static java.util.concurrent.locks.Condition c1 = lock.newCondition();
public final static java.util.concurrent.locks.Condition c2 = lock.newCondition();
public final static java.util.concurrent.locks.Condition c3 = lock.newCondition();

public static int num = 1;

public static void main(String[] args) {
executor.execute(()->{
while (num<=100){
lock.lock();
c2.signal();
System.out.println(Thread.currentThread().getName()+":"+num);
num++;
try {
c1.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
lock.unlock();
}
});a
executor.execute(()->{
while (num<=100){
lock.lock();
c3.signal();
System.out.println(Thread.currentThread().getName()+":"+num);
num++;
try {
c2.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
lock.unlock();
}
});
executor.execute(()->{
while (num<=100){
lock.lock();
c1.signal();
System.out.println(Thread.currentThread().getName()+":"+num);
num++;
try {
c3.await();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
lock.unlock();
}
});
}
}

阻塞队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
package com.atzrh.多线程;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;

/**
* @author zrh
* @version 1.0.0
* @title Condition
* @description <用Condition实现有界阻塞队列>
* @create 2026/4/3 14:00
**/
public class Condition {
public static BlockQueue queue = new BlockQueue();
public static void main(String[] args) throws InterruptedException {
BlockQueue q = new BlockQueue();
System.out.println( q);
new Thread(() -> {
try {
Thread.sleep(5000);
q.put(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}).start();
int i = q.get();
System.out.println( i);

}


}
class BlockQueue{
private final int size = 3;
private final ReentrantLock lock = new ReentrantLock();
private final java.util.concurrent.locks.Condition notFull = lock.newCondition();
private final java.util.concurrent.locks.Condition notEmpty = lock.newCondition();

private final List<Integer> list = new ArrayList<>(size);
public void put(int i) throws InterruptedException {
lock.lock();
while (list.size() == size){
notFull.await();
}
list.add(i);
notEmpty.signal();
lock.unlock();
}

public int get() throws InterruptedException {
lock.lock();
while (list.size() == 0){
notEmpty.await();
}
Integer remove = list.remove(0);
notFull.signal();
lock.unlock();
return remove;
}

}