多线程手撕

多线程手撕

1. 单例模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Singleton{
public static volatile Singleton singleton;

private Singleton(){

}

public static Singleton getInstance(){
if(singleton == null){
synchronized(Singleton.class){
if(singleton == null){
singleton = new Singleton();
}
}
}
return singleton;
}
}

2. 三个线程交替打印ABC

无限打印

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
public class ABCPrinter {
private static final Object lock = new Object();
private volatile static int state = 0;

public static void main(String[] args) {
new Thread(new PrintTask('A', 0), "Thread-A").start();
new Thread(new PrintTask('B', 1), "Thread-B").start();
new Thread(new PrintTask('C', 2), "Thread-C").start();
}

static class PrintTask implements Runnable {
private final char targetChar;
private final int targetState;

public PrintTask(char targetChar, int targetState) {
this.targetChar = targetChar;
this.targetState = targetState;
}

@Override
public void run() {
synchronized (lock) {
try {
while (true) {
while (state != targetState) {
lock.wait();
}
System.out.println(targetChar);
state = (state + 1) % 3;
lock.notifyAll();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
}

限制只打印前100个

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
public class ABCPrinter {
private static final Object lock = new Object();
private volatile static int state = 0;

public static void main(String[] args) {
new Thread(new PrintTask('A', 0), "Thread-A").start();
new Thread(new PrintTask('B', 1), "Thread-B").start();
new Thread(new PrintTask('C', 2), "Thread-C").start();
}

static class PrintTask implements Runnable {
private final char targetChar;
private final int targetState;

public PrintTask(char targetChar, int targetState) {
this.targetChar = targetChar;
this.targetState = targetState;
}

@Override
public void run() {
synchronized (lock) {
try {
while (state < 100) {
while ((state % 3) != targetState && state < 100) {
lock.wait();
}
if(state < 100){
System.out.println(Thread.currentThread().getName() + " - " + state + " : " + targetChar);
state++;
lock.notifyAll();
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}
}

3. 交替打印0 - 100 内的奇偶数

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
public class OddEvenPrinter {

private static int count = 1;
private static final Object monitor = new Object();

static class Printer implements Runnable {
@Override
public void run() {
synchronized (monitor){
while(count <= 100){
System.out.println(Thread.currentThread().getName() + ": " + count++);
monitor.notify();
if(count <= 100){
try {
monitor.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
}
}

public static void main(String[] args) {
new Thread(new Printer(), "odd").start();
new Thread(new Printer(), "even").start();
}
}

4. 生产者-消费者

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
import java.util.concurrent.LinkedBlockingDeque;
import java.util.Random;

public class ProduceConsumer {
private static final int MAX_QUEUE_SIZE = 2;
private static LinkedBlockingDeque<Integer> queue = new LinkedBlockingDeque<>(MAX_QUEUE_SIZE);
private static Random random = new Random();

public static void main(String[] args) {
for(int i = 0; i < 5; i++){
new Thread(new Producer(), "Producer-" + i).start();
new Thread(new Consumer(), "Consumer-" + i).start();
}
}


static class Producer implements Runnable {
@Override
public void run() {
try{
while(!Thread.currentThread().isInterrupted()){
int i = random.nextInt(100);
queue.put(i);
System.out.println(Thread.currentThread().getName() + " produced: " + i);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}

static class Consumer implements Runnable {
@Override
public void run() {
try{
while(!Thread.currentThread().isInterrupted()){
int i = queue.take();
System.out.println(Thread.currentThread().getName() + " consumed: " + i);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
}

5. 死锁

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
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;

public class DeadLockDemo {

public static final Object resource1 = new Object();
public static final Object resource2 = new Object();

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

new Thread(() -> {
synchronized (resource2) {
System.out.println(Thread.currentThread().getName() + " got resource2");
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println(Thread.currentThread().getName() + " waiting resource1");
synchronized (resource1) {
System.out.println(Thread.currentThread().getName() + " got resource1");
}
}
}, "Thread-2").start();

ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
long[] allThreadIds = threadMXBean.getAllThreadIds();
for (long threadId : allThreadIds) {
ThreadInfo threadInfo = threadMXBean.getThreadInfo(threadId);
if (!threadInfo.getThreadName().equals("Thread-1") && !threadInfo.getThreadName().equals("Thread-2")) {
continue;
}
System.out.println("线程名称:" + threadInfo.getThreadName());
System.out.println("线程状态:" + threadInfo.getThreadState());
}
}
}


多线程手撕
http://example.com/2026/01/14/多线程手撕/
作者
Kon4tsu
发布于
2026年1月14日
许可协议