并发编程是指同时执行多个任务,以提高程序的性能和响应速度。Java提供了丰富的并发编程工具和类。
6.1 线程的创建与运行
6.1.1 继承Thread类
我们可以通过继承Thread类来创建线程。
示例
// 创建一个继承Thread类的自定义线程类class MyThread extends Thread {@Overridepublic void run() {// run()方法中定义线程的具体任务for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " - " + i);try {// 暂停线程1秒Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}// 使用自定义线程类创建并启动线程public class Main {public static void main(String[] args) {MyThread thread1 = new MyThread();MyThread thread2 = new MyThread();// 启动线程thread1.start();thread2.start();}}
6.1.2 实现Runnable接口
我们还可以通过实现Runnable接口来创建线程,这种方式更灵活,因为它支持多继承。
示例
// 创建一个实现Runnable接口的自定义线程类class MyRunnable implements Runnable {@Overridepublic void run() {// run()方法中定义线程的具体任务for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " - " + i);try {// 暂停线程1秒Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}// 使用自定义Runnable类创建并启动线程public class Main {public static void main(String[] args) {Thread thread1 = new Thread(new MyRunnable());Thread thread2 = new Thread(new MyRunnable());// 启动线程thread1.start();thread2.start();}}
6.2 并发工具类
Java提供了一些常用的并发工具类,帮助我们更好地管理线程。
6.2.1 Executors
Executors类用于创建和管理线程池。
示例
import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;// 创建一个实现Runnable接口的自定义任务类class MyTask implements Runnable {@Overridepublic void run() {// run()方法中定义任务的具体内容for (int i = 0; i < 5; i++) {System.out.println(Thread.currentThread().getName() + " - " + i);try {// 暂停线程1秒Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}// 使用Executors创建并管理线程池public class Main {public static void main(String[] args) {// 创建固定大小的线程池ExecutorService executorService = Executors.newFixedThreadPool(2);// 提交任务给线程池执行executorService.submit(new MyTask());executorService.submit(new MyTask());// 关闭线程池executorService.shutdown();}}
6.2.2 CountDownLatch
CountDownLatch是一个同步工具类,用于使一个或多个线程等待其他线程完成一组特定操作。
示例
import java.util.concurrent.CountDownLatch;// 创建一个实现Runnable接口的自定义任务类class Worker implements Runnable {private CountDownLatch latch;// 构造方法接收CountDownLatch对象public Worker(CountDownLatch latch) {this.latch = latch;}@Overridepublic void run() {// run()方法中定义任务的具体内容System.out.println(Thread.currentThread().getName() + " is working");try {// 模拟任务执行时间Thread.sleep((int) (Math.random() * 1000));} catch (InterruptedException e) {e.printStackTrace();}// 任务完成后,调用countDown()方法latch.countDown();System.out.println(Thread.currentThread().getName() + " finished working");}}// 使用CountDownLatch同步多个线程public class Main {public static void main(String[] args) {// 创建CountDownLatch对象,设置计数为3CountDownLatch latch = new CountDownLatch(3);// 创建并启动多个Worker线程new Thread(new Worker(latch)).start();new Thread(new Worker(latch)).start();new Thread(new Worker(latch)).start();try {// 主线程等待所有Worker线程完成任务latch.await();} catch (InterruptedException e) {e.printStackTrace();}// 所有Worker线程完成任务后,继续执行主线程System.out.println("All workers finished. Main thread continues.");}}
6.3 Java内存模型与锁
Java内存模型(JMM)定义了Java程序中变量的读写规则和线程间的可见性。锁用于确保线程间的同步和数据一致性。
6.3.1 synchronized关键字
synchronized关键字用于方法或代码块,确保同一时间只有一个线程可以执行同步代码。
示例
// 创建一个共享资源类class Counter {private int count = 0;// 使用synchronized方法确保线程安全public synchronized void increment() {count++;}public synchronized int getCount() {return count;}}// 创建一个实现Runnable接口的自定义任务类class IncrementTask implements Runnable {private Counter counter;// 构造方法接收Counter对象public IncrementTask(Counter counter) {this.counter = counter;}@Overridepublic void run() {// run()方法中定义任务的具体内容for (int i = 0; i < 1000; i++) {counter.increment();}}}// 使用synchronized关键字同步线程操作public class Main {public static void main(String[] args) {Counter counter = new Counter();// 创建并启动多个IncrementTask线程Thread thread1 = new Thread(new IncrementTask(counter));Thread thread2 = new Thread(new IncrementTask(counter));thread1.start();thread2.start();try {// 等待所有线程完成任务thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}// 获取并输出计数器的最终值System.out.println("Final count: " + counter.getCount());}}
6.3.2 ReentrantLock
ReentrantLock是一个可重入的锁,提供了与synchronized相同的基本功能,但更灵活。
示例
import java.util.concurrent.locks.ReentrantLock;// 创建一个共享资源类class Counter {private int count = 0;private final ReentrantLock lock = new ReentrantLock();// 使用ReentrantLock确保线程安全public void increment() {lock.lock(); // 获取锁try {count++;} finally {lock.unlock(); // 释放锁}}public int getCount() {lock.lock(); // 获取锁try {return count;} finally {lock.unlock(); // 释放锁}}}// 创建一个实现Runnable接口的自定义任务类class IncrementTask implements Runnable {private Counter counter;// 构造方法接收Counter对象public IncrementTask(Counter counter) {this.counter = counter;}@Overridepublic void run() {// run()方法中定义任务的具体内容for (int i = 0; i < 1000; i++) {counter.increment();}}}// 使用ReentrantLock同步线程操作public class Main {public static void main(String[] args) {Counter counter = new Counter();// 创建并启动多个IncrementTask线程Thread thread1 = new Thread(new IncrementTask(counter));Thread thread2 = new Thread(new IncrementTask(counter));thread1.start();thread2.start();try {// 等待所有线程完成任务thread1.join();thread2.join();} catch (InterruptedException e) {e.printStackTrace();}// 获取并输出计数器的最终值System.out.println("Final count: " + counter.getCount());}}
