并发编程是指同时执行多个任务,以提高程序的性能和响应速度。Java提供了丰富的并发编程工具和类。

6.1 线程的创建与运行

6.1.1 继承Thread类

我们可以通过继承Thread类来创建线程。

示例

  1. // 创建一个继承Thread类的自定义线程类
  2. class MyThread extends Thread {
  3. @Override
  4. public void run() {
  5. // run()方法中定义线程的具体任务
  6. for (int i = 0; i < 5; i++) {
  7. System.out.println(Thread.currentThread().getName() + " - " + i);
  8. try {
  9. // 暂停线程1秒
  10. Thread.sleep(1000);
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. }
  15. }
  16. }
  17. // 使用自定义线程类创建并启动线程
  18. public class Main {
  19. public static void main(String[] args) {
  20. MyThread thread1 = new MyThread();
  21. MyThread thread2 = new MyThread();
  22. // 启动线程
  23. thread1.start();
  24. thread2.start();
  25. }
  26. }

6.1.2 实现Runnable接口

我们还可以通过实现Runnable接口来创建线程,这种方式更灵活,因为它支持多继承。

示例

  1. // 创建一个实现Runnable接口的自定义线程类
  2. class MyRunnable implements Runnable {
  3. @Override
  4. public void run() {
  5. // run()方法中定义线程的具体任务
  6. for (int i = 0; i < 5; i++) {
  7. System.out.println(Thread.currentThread().getName() + " - " + i);
  8. try {
  9. // 暂停线程1秒
  10. Thread.sleep(1000);
  11. } catch (InterruptedException e) {
  12. e.printStackTrace();
  13. }
  14. }
  15. }
  16. }
  17. // 使用自定义Runnable类创建并启动线程
  18. public class Main {
  19. public static void main(String[] args) {
  20. Thread thread1 = new Thread(new MyRunnable());
  21. Thread thread2 = new Thread(new MyRunnable());
  22. // 启动线程
  23. thread1.start();
  24. thread2.start();
  25. }
  26. }

6.2 并发工具类

Java提供了一些常用的并发工具类,帮助我们更好地管理线程。

6.2.1 Executors

Executors类用于创建和管理线程池。

示例

  1. import java.util.concurrent.ExecutorService;
  2. import java.util.concurrent.Executors;
  3. // 创建一个实现Runnable接口的自定义任务类
  4. class MyTask implements Runnable {
  5. @Override
  6. public void run() {
  7. // run()方法中定义任务的具体内容
  8. for (int i = 0; i < 5; i++) {
  9. System.out.println(Thread.currentThread().getName() + " - " + i);
  10. try {
  11. // 暂停线程1秒
  12. Thread.sleep(1000);
  13. } catch (InterruptedException e) {
  14. e.printStackTrace();
  15. }
  16. }
  17. }
  18. }
  19. // 使用Executors创建并管理线程池
  20. public class Main {
  21. public static void main(String[] args) {
  22. // 创建固定大小的线程池
  23. ExecutorService executorService = Executors.newFixedThreadPool(2);
  24. // 提交任务给线程池执行
  25. executorService.submit(new MyTask());
  26. executorService.submit(new MyTask());
  27. // 关闭线程池
  28. executorService.shutdown();
  29. }
  30. }

6.2.2 CountDownLatch

CountDownLatch是一个同步工具类,用于使一个或多个线程等待其他线程完成一组特定操作。

示例

  1. import java.util.concurrent.CountDownLatch;
  2. // 创建一个实现Runnable接口的自定义任务类
  3. class Worker implements Runnable {
  4. private CountDownLatch latch;
  5. // 构造方法接收CountDownLatch对象
  6. public Worker(CountDownLatch latch) {
  7. this.latch = latch;
  8. }
  9. @Override
  10. public void run() {
  11. // run()方法中定义任务的具体内容
  12. System.out.println(Thread.currentThread().getName() + " is working");
  13. try {
  14. // 模拟任务执行时间
  15. Thread.sleep((int) (Math.random() * 1000));
  16. } catch (InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. // 任务完成后,调用countDown()方法
  20. latch.countDown();
  21. System.out.println(Thread.currentThread().getName() + " finished working");
  22. }
  23. }
  24. // 使用CountDownLatch同步多个线程
  25. public class Main {
  26. public static void main(String[] args) {
  27. // 创建CountDownLatch对象,设置计数为3
  28. CountDownLatch latch = new CountDownLatch(3);
  29. // 创建并启动多个Worker线程
  30. new Thread(new Worker(latch)).start();
  31. new Thread(new Worker(latch)).start();
  32. new Thread(new Worker(latch)).start();
  33. try {
  34. // 主线程等待所有Worker线程完成任务
  35. latch.await();
  36. } catch (InterruptedException e) {
  37. e.printStackTrace();
  38. }
  39. // 所有Worker线程完成任务后,继续执行主线程
  40. System.out.println("All workers finished. Main thread continues.");
  41. }
  42. }

6.3 Java内存模型与锁

Java内存模型(JMM)定义了Java程序中变量的读写规则和线程间的可见性。锁用于确保线程间的同步和数据一致性。

6.3.1 synchronized关键字

synchronized关键字用于方法或代码块,确保同一时间只有一个线程可以执行同步代码。

示例

  1. // 创建一个共享资源类
  2. class Counter {
  3. private int count = 0;
  4. // 使用synchronized方法确保线程安全
  5. public synchronized void increment() {
  6. count++;
  7. }
  8. public synchronized int getCount() {
  9. return count;
  10. }
  11. }
  12. // 创建一个实现Runnable接口的自定义任务类
  13. class IncrementTask implements Runnable {
  14. private Counter counter;
  15. // 构造方法接收Counter对象
  16. public IncrementTask(Counter counter) {
  17. this.counter = counter;
  18. }
  19. @Override
  20. public void run() {
  21. // run()方法中定义任务的具体内容
  22. for (int i = 0; i < 1000; i++) {
  23. counter.increment();
  24. }
  25. }
  26. }
  27. // 使用synchronized关键字同步线程操作
  28. public class Main {
  29. public static void main(String[] args) {
  30. Counter counter = new Counter();
  31. // 创建并启动多个IncrementTask线程
  32. Thread thread1 = new Thread(new IncrementTask(counter));
  33. Thread thread2 = new Thread(new IncrementTask(counter));
  34. thread1.start();
  35. thread2.start();
  36. try {
  37. // 等待所有线程完成任务
  38. thread1.join();
  39. thread2.join();
  40. } catch (InterruptedException e) {
  41. e.printStackTrace();
  42. }
  43. // 获取并输出计数器的最终值
  44. System.out.println("Final count: " + counter.getCount());
  45. }
  46. }

6.3.2 ReentrantLock

ReentrantLock是一个可重入的锁,提供了与synchronized相同的基本功能,但更灵活。

示例

  1. import java.util.concurrent.locks.ReentrantLock;
  2. // 创建一个共享资源类
  3. class Counter {
  4. private int count = 0;
  5. private final ReentrantLock lock = new ReentrantLock();
  6. // 使用ReentrantLock确保线程安全
  7. public void increment() {
  8. lock.lock(); // 获取锁
  9. try {
  10. count++;
  11. } finally {
  12. lock.unlock(); // 释放锁
  13. }
  14. }
  15. public int getCount() {
  16. lock.lock(); // 获取锁
  17. try {
  18. return count;
  19. } finally {
  20. lock.unlock(); // 释放锁
  21. }
  22. }
  23. }
  24. // 创建一个实现Runnable接口的自定义任务类
  25. class IncrementTask implements Runnable {
  26. private Counter counter;
  27. // 构造方法接收Counter对象
  28. public IncrementTask(Counter counter) {
  29. this.counter = counter;
  30. }
  31. @Override
  32. public void run() {
  33. // run()方法中定义任务的具体内容
  34. for (int i = 0; i < 1000; i++) {
  35. counter.increment();
  36. }
  37. }
  38. }
  39. // 使用ReentrantLock同步线程操作
  40. public class Main {
  41. public static void main(String[] args) {
  42. Counter counter = new Counter();
  43. // 创建并启动多个IncrementTask线程
  44. Thread thread1 = new Thread(new IncrementTask(counter));
  45. Thread thread2 = new Thread(new IncrementTask(counter));
  46. thread1.start();
  47. thread2.start();
  48. try {
  49. // 等待所有线程完成任务
  50. thread1.join();
  51. thread2.join();
  52. } catch (InterruptedException e) {
  53. e.printStackTrace();
  54. }
  55. // 获取并输出计数器的最终值
  56. System.out.println("Final count: " + counter.getCount());
  57. }
  58. }