引言
在当今高并发、高性能的软件开发需求下,Java作为一门成熟且广泛应用的编程语言,其并发编程特性显得尤为重要。掌握Java并发编程能够帮助开发者充分利用多核CPU的计算能力,提高程序的执行效率和响应速度。本文将深入探讨Java并发编程的基础知识、核心组件以及实际应用中的常见问题和解决方案。
一、Java并发编程基础
1.1 进程与线程
进程是操作系统资源分配的基本单位,而线程是CPU调度和执行的基本单位。一个进程可以包含多个线程,线程共享进程的内存空间,这使得线程之间的通信比进程之间更为高效。在Java中,通过Thread类来创建和操作线程。
java
public class SimpleThreadExample {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
System.out.println(“这是一个新线程在运行”);
});
thread.start();
System.out.println(“主线程继续执行”);
}
}
1.2 线程的生命周期
线程的生命周期包括新建、就绪、运行、阻塞和死亡五个状态。了解线程的状态转换对于编写正确的并发程序至关重要。例如,线程可以通过调用wait()、sleep()等方法进入阻塞状态,通过notify()或notifyAll()方法唤醒处于阻塞状态的线程。
二、Java并发核心组件
2.1 锁机制
2.1.1 synchronized关键字
synchronized是Java中最基本的同步机制,它可以用于修饰方法或代码块。当多个线程访问同一个synchronized修饰的代码时,只有一个线程能够获取到锁,其他线程需要等待锁释放后才能继续执行。
java
public class SynchronizedExample {
private int count = 0;
public synchronized void increment() { count++; } public static void main(String[] args) throws InterruptedException { SynchronizedExample example = new SynchronizedExample(); 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("最终结果: " + example.count); }}
2.1.2 ReentrantLock
ReentrantLock是java.util.concurrent.locks包下提供的可重入锁,相比synchronized关键字,它提供了更灵活的锁操作,例如尝试获取锁、可中断的锁获取等。
java
import java.util.concurrent.locks.ReentrantLock;
public class ReentrantLockExample {
private ReentrantLock lock = new ReentrantLock();
private int count = 0;
public void increment() { lock.lock(); try { count++; } finally { lock.unlock(); } } public static void main(String[] args) throws InterruptedException { ReentrantLockExample example = new ReentrantLockExample(); 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("最终结果: " + example.count); }}
2.2 线程通信
2.2.1 wait()、notify()和notifyAll()
这三个方法是Object类提供的,用于线程之间的通信。wait()方法使当前线程进入等待状态,并释放锁;notify()方法唤醒一个正在等待该对象锁的线程;notifyAll()方法唤醒所有正在等待该对象锁的线程。
java
public class WaitNotifyExample {
private static final Object lock = new Object();
private static boolean conditionMet = false;
public static void main(String[] args) { Thread waitingThread = new Thread(() -> { synchronized (lock) { while (!conditionMet) { try { System.out.println("等待线程等待条件满足"); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("等待线程条件满足,继续执行"); } }); Thread notifyingThread = new Thread(() -> { synchronized (lock) { try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } conditionMet = true; lock.notify(); System.out.println("通知线程通知等待线程"); } }); waitingThread.start(); notifyingThread.start(); }}