从零开始写多线程

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
1. Java 多线程的基本概念
1.1 线程与进程
进程:是操作系统分配资源的基本单位,每个进程都有独立的内存空间。
线程:是进程内的一个执行单元,同一进程中的线程共享进程的内存空间,线程间的通信更为高效。
1.2 线程的好处
提高系统响应性:可以实现用户界面与后台处理的并发执行,使得程序即使在处理耗时操作时也能保持响应。
提高性能:充分利用多核处理器的能力,同时处理多个任务。
2. 创建线程的两种方式
2.1 继承 Thread 类
可以通过继承 Thread 类并重写 run() 方法来创建线程。
 
1class MyThread extends Thread {
2    @Override
3    public void run() {
4        System.out.println("Thread running...");
5    }
6   
7    public static void main(String[] args) {
8        MyThread thread = new MyThread();
9        thread.start(); // 启动线程
10    }
11}
2.2 实现 Runnable 接口
也可以实现 Runnable 接口,并将其实例作为参数传递给 Thread 的构造函数。
 
1class MyRunnable implements Runnable {
2    @Override
3    public void run() {
4        System.out.println("Runnable running...");
5    }
6   
7    public static void main(String[] args) {
8        Thread thread = new Thread(new MyRunnable());
9        thread.start();
10    }
11}
3. 线程的生命周期
线程的生命周期包括以下几个阶段:
 
新建 (NEW):当一个线程对象被创建但尚未启动时。
就绪 (RUNNABLE):线程被启动后,等待 CPU 时间片。
运行 (RUNNABLE):线程获得了 CPU 时间片并开始执行。
阻塞 (BLOCKED):线程因等待某种条件(如 I/O 操作或同步锁)而暂时停止运行。
等待/休眠 (WAITING):线程因等待特定事件的发生(如 wait() 方法)而暂停运行。
定时等待 (TIMED_WAITING):线程因等待一定时间(如 sleep() 方法)而暂停运行。
终止 (TERMINATED):线程执行完毕或被异常终止。
4. 线程同步
4.1 同步锁
为了保证多线程环境下对共享资源的正确访问,可以使用同步锁(Synchronized)来保护临界区。
 
1public class Counter {
2    private int count = 0;
3   
4    public synchronized void increment() {
5        count++;
6    }
7   
8    public synchronized int getCount() {
9        return count;
10    }
11}
4.2 volatile 关键字
volatile 关键字可以用来标记一个变量是共享的,确保了对变量的可见性和禁止指令重排。
 
1public class Counter {
2    private volatile int count = 0;
3   
4    public void increment() {
5        count++;
6    }
7   
8    public int getCount() {
9        return count;
10    }
11}
4.3 Lock 接口
Lock 接口提供了更灵活的锁定机制,可以实现更复杂的同步策略。
 
1import java.util.concurrent.locks.Lock;
2import java.util.concurrent.locks.ReentrantLock;
3
4public class Counter {
5    private int count = 0;
6    private final Lock lock = new ReentrantLock();
7   
8    public void increment() {
9        lock.lock();
10        try {
11            count++;
12        } finally {
13            lock.unlock();
14        }
15    }
16   
17    public int getCount() {
18        return count;
19    }
20}
5. 线程间通信
5.1 wait() 和 notify()
wait() 和 notify() 方法可以用来实现线程间的通信。
 
1public class Counter {
2    private int count = 0;
3    private final Object monitor = new Object();
4   
5    public void increment() {
6        synchronized (monitor) {
7            count++;
8            monitor.notify();
9        }
10    }
11   
12    public void decrement() {
13        synchronized (monitor) {
14            while (count == 0) {
15                try {
16                    monitor.wait();
17                } catch (InterruptedException e) {
18                    e.printStackTrace();
19                }
20            }
21            count--;
22        }
23    }
24}
5.2 生产者-消费者模式
生产者-消费者模式是一种经典的线程协作模型,通过队列来实现生产者和消费者之间的解耦。
 
1import java.util.concurrent.BlockingQueue;
2import java.util.concurrent.LinkedBlockingQueue;
3
4public class ProducerConsumerDemo {
5    private static final BlockingQueue<Integer> queue = new LinkedBlockingQueue<>(10);
6   
7    public static void main(String[] args) {
8        Thread producer = new Thread(() -> {
9            try {
10                for (int i = 0; i < 100; i++) {
11                    queue.put(i);
12                    System.out.println("Produced: " + i);
13                }
14            } catch (InterruptedException e) {
15                e.printStackTrace();
16            }
17        });
18       
19        Thread consumer = new Thread(() -> {
20            try {
21                for (int i = 0; i < 100; i++) {
22                    int item = queue.take();
23                    System.out.println("Consumed: " + item);
24                }
25            } catch (InterruptedException e) {
26                e.printStackTrace();
27            }
28        });
29       
30        producer.start();
31        consumer.start();
32    }
33}
6. 线程池
线程池可以有效地管理线程,避免频繁创建和销毁线程所带来的开销。
 
1import java.util.concurrent.ExecutorService;
2import java.util.concurrent.Executors;
3
4public class ThreadPoolDemo {
5    public static void main(String[] args) {
6        ExecutorService executor = Executors.newFixedThreadPool(5);
7       
8        for (int i = 0; i < 10; i++) {
9            executor.submit(() -> {
10                System.out.println(Thread.currentThread().getName() + " is running");
11            });
12        }
13       
14        executor.shutdown();
15    }
16}
7. 线程中断
线程中断是一种通知线程终止的方式。
 
1public class ThreadInterruptDemo {
2    public static void main(String[] args) throws InterruptedException {
3        Thread thread = new Thread(() -> {
4            try {
5                while (!Thread.currentThread().isInterrupted()) {
6                    Thread.sleep(1000);
7                    System.out.println("Running...");
8                }
9            } catch (InterruptedException e) {
10                System.out.println("Interrupted!");
11                Thread.currentThread().interrupt(); // 重置中断标志
12            }
13        });
14       
15        thread.start();
16        Thread.sleep(5000);
17        thread.interrupt();
18    }
19}
8. 线程安全的容器
Java 提供了一些线程安全的容器类,如 Vector、ConcurrentHashMap 等。
 
1import java.util.concurrent.ConcurrentHashMap;
2
3public class ThreadSafeContainerDemo {
4    private static ConcurrentHashMap<Integer, String> map = new ConcurrentHashMap<>();
5   
6    public static void main(String[] args) {
7        Thread t1 = new Thread(() -> {
8            for (int i = 0; i < 100; i++) {
9                map.put(i, "Value " + i);
10            }
11        });
12       
13        Thread t2 = new Thread(() -> {
14            for (int i = 0; i < 100; i++) {
15                map.remove(i);
16            }
17        });
18       
19        t1.start();
20        t2.start();
21    }
22}

  

posted @   XiangdxDu  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示