Java 多线程并发面试
Java 是一种广泛使用的编程语言,其内置的多线程支持让开发者能够有效地实现并发编程。然而,随着并发编程的复杂性增加,理解其中的概念至关重要。在本文中,我们将探讨 Java 多线程的基础知识、相关机制以及一些示例代码,并为即将到来的面试做准备。
1. 多线程的基本概念
多线程就是允许一个程序在独立的线程中同时执行多个任务。Java 中的每个线程都是一个 Thread
实例,线程之间可以共享数据。
1.1 创建线程
我们可以通过两种方式创建线程:继承 Thread
类和实现 Runnable
接口。
1.1.1 继承 Thread 类
class MyThread extends Thread {
public void run() {
System.out.println("Thread is running");
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 启动线程
}
}
1.1.2 实现 Runnable 接口
class MyRunnable implements Runnable {
public void run() {
System.out.println("Runnable thread is running");
}
}
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(new MyRunnable());
thread.start(); // 启动线程
}
}
1.2 线程的生命周期
Java 线程的生命周期包括 新建、可运行、阻塞、等待、终止等状态。
stateDiagram
[*] --> 新建
新建 --> 可运行 : start()
可运行 --> 阻塞 : sleep() 或 wait()
阻塞 --> 可运行 : notify() 或 sleep 到期
可运行 --> 终止 : run() 完成
2. 线程同步
多线程程序很容易出现数据不一致的问题,因此需要使用同步机制。Java 提供了 synchronized
关键字和 java.util.concurrent
包中的其他工具。
2.1 使用 synchronized
class Counter {
private int count = 0;
public synchronized void increment() {
count++;
}
public int getCount() {
return count;
}
}
2.2 使用 ReentrantLock
ReentrantLock
提供了比 synchronized
更灵活的锁定机制。
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
class Counter {
private int count = 0;
private Lock lock = new ReentrantLock();
public void increment() {
lock.lock();
try {
count++;
} finally {
lock.unlock();
}
}
public int getCount() {
return count;
}
}
3. 线程间通信
在多线程环境下,有时需要线程之间进行通信。Java 提供了 wait()
、notify()
和 notifyAll()
方法。
class SharedResource {
private int data;
public synchronized void produce(int value) {
data = value;
notify(); // 唤醒等待的线程
}
public synchronized int consume() throws InterruptedException {
wait(); // 等待生产者生产数据
return data;
}
}
4. 使用线程池
使用线程池能够有效地管理和复用线程,避免频繁的创建和销毁。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(2);
for (int i = 0; i < 5; i++) {
executor.submit(() -> {
System.out.println("Running task in: " + Thread.currentThread().getName());
});
}
executor.shutdown();
}
}
5. 旅行图的使用
在日常的多线程开发中,开发者遵循一定的流程来确保代码的正确性和性能。以下是一个典型的旅行图示例:
journey
title 多线程编程之旅
section 学习线程基础
了解`Thread`类: 5: Me
练习创建线程: 3: Me
section 理解同步与通信
学习`synchronized`: 5: Me
深入`wait()`与`notify()`: 4: Me
section 并发工具的使用
探索`ExecutorService`: 4: Me
学习`ReentrantLock`: 3: Me
结尾
Java 多线程编程是一个复杂但有趣的领域,通过学习和应用相关概念和工具,开发者能够创建出高效且可扩展的程序。在面试中,掌握多线程的基本概念、生命周期、同步机制、线程间通信以及线程池等知识点是至关重要的。希望这篇文章能帮助你更好地理解 Java 的多线程机制,并在面试中脱颖而出。