1. 线程的生命周期
线程的生命周期包括以下状态:
- 新建(New):通过 new 关键字或线程池创建新线程,但尚未启动。
- 就绪(Runnable):线程被创建后,调用 start() 方法后进入就绪状态,等待获取 CPU 资源。
- 运行(Running):线程获得了 CPU 资源,开始执行任务。
- 阻塞(Blocked):线程因为某些原因暂时停止执行,例如等待 I/O 操作完成或等待获取锁。
- 终止(Terminated):线程执行完任务或调用了 stop() 方法导致线程终止。
下面是一个简单的示例代码:
public class ThreadLifecycleExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println("线程执行任务...");
});
System.out.println("线程状态:" + thread.getState()); // 输出 NEW
thread.start();
System.out.println("线程状态:" + thread.getState()); // 输出 RUNNABLE
// 可以在这里加入一些代码使线程进入阻塞状态,如线程 sleep、等待锁等
try {
thread.join(); // 等待线程执行完毕
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("线程状态:" + thread.getState()); // 输出 TERMINATED
}
}
2. 线程同步与互斥
多个线程访问共享资源时,可能导致数据不一致或其他问题。为了解决这个问题,需要使用同步和互斥机制。在Java中,可以使用 synchronized 关键字来实现线程同步。
public class SynchronizationExample {
private int count = 0;
public synchronized void increment() {
count++;
}
public synchronized int getCount() {
return count;
}
public static void main(String[] args) throws InterruptedException {
SynchronizationExample example = new SynchronizationExample();
Thread thread1 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
Thread thread2 = new Thread(() -> {
for (int i = 0; i < 1000; i++) {
example.increment();
}
});
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.println("Count: " + example.getCount()); // 输出 2000
}
}
3. 线程通信
在线程之间进行通信是一种重要的技术,以实现协作。常见的线程通信方式包括 wait()、notify()、notifyAll() 方法。
public class ThreadCommunicationExample {
public static void main(String[] args) {
final Processor processor = new Processor();
Thread producerThread = new Thread(() -> {
try {
processor.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
Thread consumerThread = new Thread(() -> {
try {
processor.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
producerThread.start();
consumerThread.start();
}
static class Processor {
public void produce() throws InterruptedException {
synchronized (this) {
System.out.println("Producer 线程开始执行生产任务...");
wait(); // 等待消费者消费
System.out.println("Producer 线程恢复执行...");
}
}
public void consume() throws InterruptedException {
Thread.sleep(2000); // 模拟消费者任务耗时
synchronized (this) {
System.out.println("Consumer 线程开始执行消费任务...");
notify(); // 通知生产者可以继续生产
System.out.println("Consumer 线程通知生产者任务已完成...");
}
}
}
}
4. 线程池
线程池是一种管理和复用线程的机制,可以有效地控制线程的创建和销毁,减少因线程创建销毁带来的开销。Java 提供了 Executor 框架来支持线程池的使用。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(3); // 创建固定大小的线程池
for (int i = 0; i < 5; i++) {
executor.submit(() -> {
System.out.println("线程 " + Thread.currentThread().getName() + " 正在执行任务");
try {
Thread.sleep(1000); // 模拟任务执行耗时
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
executor.shutdown(); // 关闭线程池
}
}
5. 并发集合
Java 并发包提供了一些并发安全的集合类,如 ConcurrentHashMap、ConcurrentLinkedQueue 等,用于在多线程环境下进行数据存取操作。
import java.util.concurrent.ConcurrentHashMap;
public class ConcurrentCollectionExample {
public static void main(String[] args) {
ConcurrentHashMap<String, Integer> map = new ConcurrentHashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
System.out.println("ConcurrentHashMap: " + map); // 输出 ConcurrentHashMap: {A=1, B=2, C=3}
}
}
总结
以上是对线程生命周期、线程同步与互斥、线程通信、线程池和并发集合等主题的详细说明,并配以相关的Java代码示例。理解和掌握这些主题将有助于你更好地进行多线程编程。
评论区