Java并发编程从入门到进阶 多场景实战
Java并发编程是现代软件开发中的重要技能,特别是在高性能和高可用性要求的系统中。以下是从入门到进阶的Java并发编程知识,结合多场景实战进行详细介绍:
一、Java并发编程基础知识
- 并发与并行的概念
- 并发:指在同一时间段内,可以有多个执行路径在运行,但不一定是同时执行。在Java中,这通常是通过多线程实现的。
- 并行:指多个任务在同一时刻同时执行,这需要多核或多处理器系统。
- 线程的创建
- Java中,线程是程序执行的基本单位。一个Java应用程序至少有一个主线程(main线程)。
- 创建新线程有两种主要方式:继承Thread类、实现Runnable接口。
- 线程的生命周期
- 新建(New):线程被创建但尚未启动。
- 就绪(Runnable):线程已启动,等待CPU分配时间片。
- 运行(Running):线程正在执行。
- 阻塞(Blocked):线程因为某种原因被阻塞,等待资源。
- 死亡(Dead):线程执行完成,资源被释放。
二、Java并发编程进阶知识
- 线程池
- Java提供了多种并发工具,主要集中在java.util.concurrent包中。
- Executor框架提供了更高层次的线程管理,简化了线程的创建和管理。
- 常用的线程池有FixedThreadPool、CachedThreadPool等。
- 线程安全的数据结构
- Java提供了多种线程安全的数据结构,如ConcurrentHashMap、CopyOnWriteArrayList等。
- 这些数据结构在多线程环境下能够保证数据的一致性。
- 锁机制
- Java提供了多种锁机制,最常用的是ReentrantLock。
- 锁可以用于保护共享资源,以避免数据竞争。
三、多场景实战
- 生产者-消费者模型
- 生产者线程负责生产数据,而消费者线程负责消费数据。
- 可以使用BlockingQueue来实现这一模型。
- 示例代码:
Java
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
public class ProducerConsumerExample {
private static final BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(10);
public static void main(String[] args) {
Thread producer = new Thread(() -> {
try {
for (int i = 0; i < 20; i++) {
queue.put(i);
System.out.println("Produced: " + i);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
Thread consumer = new Thread(() -> {
try {
for (int i = 0; i < 20; i++) {
Integer value = queue.take();
System.out.println("Consumed: " + value);
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
producer.start();
consumer.start();
}
}
2. 线程安全的计数器 3. 在一些场景中,需要一个线程安全的计数器。 4. 可以使用AtomicInteger来实现。 5. Phaser控制并发任务的多个阶段 6. Phaser是一个灵活的同步屏障,可以用来控制并发任务的多个阶段。 7. 它比CyclicBarrier和CountDownLatch更加灵活。 8. 示例代码:
Java
import java.util.concurrent.Phaser;
public class PhaserExample {
public static void main(String[] args) {
Phaser phaser = new Phaser(1); // 注册主线程
for (int i = 0; i < 3; i++) {
phaser.register(); // 动态注册参与者
new Thread(new Task(phaser)).start();
}
phaser.arriveAndDeregister(); // 主线程到达并注销
// 等待所有任务完成
phaser.awaitAdvance(phaser.getPhase());
System.out.println("All tasks completed.");
}
}
class Task implements Runnable {
private Phaser phaser;
Task(Phaser phaser) {
this.phaser = phaser;
}
@Override
public void run() {
phaser.arriveAndAwaitAdvance(); // 第一个阶段
System.out.println(Thread.currentThread().getName() + " completed phase 1");
phaser.arriveAndAwaitAdvance(); // 第二个阶段
System.out.println(Thread.currentThread().getName() + " completed phase 2");
phaser.arriveAndDeregister(); // 完成所有阶段并注销
}
}
4. Semaphore控制并发访问 5. Semaphore是一个计数信号量,用于控制对共享资源的并发访问。 6. 它可以限制同时访问某个资源的线程数量。 7. 示例代码:
Java
import java.util.concurrent.Semaphore;
public class SemaphoreExample {
public static void main(String[] args) {
Semaphore semaphore = new Semaphore(3); // 允许3个线程同时访问
for (int i = 0; i < 10; i++) {
new Thread(new Worker(semaphore)).start();
}
}
}
class Worker implements Runnable {
private Semaphore semaphore;
Worker(Semaphore semaphore) {
this.semaphore = semaphore;
}
@Override
public void run() {
try {
semaphore.acquire();
System.out.println(Thread.currentThread().getName() + " acquired semaphore");
Thread.sleep(2000); // 模拟工作
System.out.println(Thread.currentThread().getName() + " released semaphore");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
semaphore.release();
}
}
}
5. Exchanger线程间数据交换 6. Exchanger是一个用于在两个线程之间交换数据的同步点。 7. 每个线程在同步点上等待,直到另一个线程到达,然后两个线程交换数据。 8. 示例代码:
Java
import java.util.concurrent.Exchanger;
public class ExchangerExample {
public static void main(String[] args) {
Exchanger<String> exchanger = new Exchanger<>();
new Thread(new Producer(exchanger)).start();
new Thread(new Consumer(exchanger)).start();
}
}
class Producer implements Runnable {
private Exchanger<String> exchanger;
Producer(Exchanger<String> exchanger) {
this.exchanger = exchanger;
}
@Override
public void run() {
try {
String data = "Data from Producer";
System.out.println("Producer is producing data: " + data);
String response = exchanger.exchange(data);
System.out.println("Producer received response: " + response);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class Consumer implements Runnable {
private Exchanger<String> exchanger;
Consumer(Exchanger<String> exchanger) {
this.exchanger = exchanger;
}
@Override
public void run() {
try {
String data = "Data from Consumer";
System.out.println("Consumer is producing data: " + data);
String response = exchanger.exchange(data);
System.out.println("Consumer received response: " + response);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
四、总结
Java并发编程是一个复杂而强大的领域,通过掌握基础知识和进阶技巧,并结合多场景实战,可以更好地利用Java提供的并发编程工具和库来实现高效、可扩展和可靠的系统。