当前位置: 首页 > article >正文

Java 多线程详解

目录

1. 引言

2. 线程的基础知识

2.1 线程与进程的区别

2.2 线程的生命周期

3. 创建线程的三种方式

3.1 继承 Thread 类

优缺点

3.2 实现 Runnable 接口

优缺点

3.3 使用 Callable 和 Future

4. 线程同步与安全

4.1 线程安全问题

4.2 使用 synchronized

4.3 使用 ReentrantLock

5. 高级多线程

5.1 线程池

5.2 并发工具类

1. CountDownLatch:等待多个线程完成任务。

6. 常见问题与优化

7. 结论


1. 引言

在现代开发中,多线程是一个关键技术。无论是服务器处理并发请求,还是在客户端实现流畅的用户体验,多线程技术都能发挥重要作用。本篇文章将从基础概念到高级应用,全面解析 Java 多线程,帮助你深入理解并应用。


2. 线程的基础知识

2.1 线程与进程的区别

  • 进程是资源分配的最小单位,彼此独立;
  • 线程是 CPU 调度的最小单位,同一进程中的线程共享内存和资源。
资源共享独立内存空间同一进程内共享
开销创建成本高较低
通信       IPC(如管道)直接共享变量

2.2 线程的生命周期

线程在 Java 中有五个状态:

  1. 新建 (New)Thread t = new Thread();
  2. 就绪 (Runnable):调用 start() 后,等待 CPU 调度。
  3. 运行 (Running):获得 CPU 时间片后执行。
  4. 阻塞 (Blocked):等待资源或信号。
  5. 终止 (Terminated):线程任务完成或被中断。

生命周期图:

 

New -> Runnable -> Running -> Terminated
          ^       |
          |       v
       Blocked <- 

 

 


3. 创建线程的三种方式

3.1 继承 Thread

通过继承 Thread 类并重写 run() 方法:

class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName() + " is running");
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread t1 = new MyThread();
        t1.start();
    }
}

 

优缺点
  • 优点:简单,代码清晰。
  • 缺点:Java 不支持多继承,限制了扩展性。

    3.2 实现 Runnable 接口

    通过实现 Runnable 接口来创建线程,避免继承限制:

    class MyRunnable implements Runnable {
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName() + " is running");
        }
    }
    
    public class Main {
        public static void main(String[] args) {
            Thread t1 = new Thread(new MyRunnable());
            t1.start();
        }
    }
    

优缺点
  • 优点:更灵活,可以继承其他类。
  • 缺点:相比直接继承 Thread,稍微复杂。

3.3 使用 CallableFuture

Runnable 不同,Callable 可以返回结果并抛出异常:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

class MyCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        return 123;
    }
}

public class Main {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        FutureTask<Integer> future = new FutureTask<>(new MyCallable());
        Thread t = new Thread(future);
        t.start();
        System.out.println("Result: " + future.get());
    }
}

 

4. 线程同步与安全

4.1 线程安全问题

多个线程同时修改共享变量可能导致数据不一致:

class Counter {
    private int count = 0;

    public void increment() {
        count++;
    }

    public int getCount() {
        return count;
    }
}

public class Main {
    public static void main(String[] args) {
        Counter counter = new Counter();
        for (int i = 0; i < 1000; i++) {
            new Thread(counter::increment).start();
        }
        System.out.println("Final count: " + counter.getCount());
    }
}

 

 

4.2 使用 synchronized

解决线程安全问题的基本方法:

class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++;
    }

    public synchronized int getCount() {
        return count;
    }
}

4.3 使用 ReentrantLock

更灵活的锁机制:

import java.util.concurrent.locks.ReentrantLock;

class Counter {
    private int count = 0;
    private ReentrantLock lock = new ReentrantLock();

    public void increment() {
        lock.lock();
        try {
            count++;
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        return count;
    }
}

 


5. 高级多线程

5.1 线程池

使用 ExecutorService 创建线程池:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {
    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() + " is running");
            });
        }

        executor.shutdown();
    }
}


5.2 并发工具类

1. CountDownLatch:等待多个线程完成任务。

 

import java.util.concurrent.CountDownLatch;

public class Main {
    public static void main(String[] args) throws InterruptedException {
        CountDownLatch latch = new CountDownLatch(3);

        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                System.out.println(Thread.currentThread().getName() + " finished");
                latch.countDown();
            }).start();
        }

        latch.await();
        System.out.println("All threads finished");
    }
}

 2. CyclicBarrier:同步多个线程。

import java.util.concurrent.CyclicBarrier;

public class Main {
    public static void main(String[] args) {
        CyclicBarrier barrier = new CyclicBarrier(3, () -> {
            System.out.println("All threads reached the barrier");
        });

        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                try {
                    System.out.println(Thread.currentThread().getName() + " is waiting");
                    barrier.await();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
}

         


6. 常见问题与优化

  1. 死锁
    • 避免锁的嵌套。
    • 按顺序获取锁。
  2. 性能问题
    • 减少锁粒度。
    • 使用并发容器,如 ConcurrentHashMap
  3. 调试技巧
    • 使用工具如 VisualVM 监控线程状态。

7. 结论

Java 多线程是开发者必备技能。通过本文的学习,你将能够创建线程、解决线程安全问题,并灵活运用线程池和并发工具类。记住,线程的强大伴随着复杂性,需要谨慎设计。欢迎大家评论区留言交流,希望文章对大家有帮助!!


 

 

 


http://www.kler.cn/a/401592.html

相关文章:

  • 反向代理模块
  • Java 核心技术卷 I 学习记录九
  • 【Vue笔记】基于vue3 + element-plus + el-dialog封装一个自定义的dialog弹出窗口组件
  • 已有docker增加端口号,不用重新创建Docker
  • OCRSpace申请free api流程
  • Linux-何为CentOS
  • 掌握SEO提升网站流量的关键在于长尾关键词的有效运用
  • Pytest 学习 @allure.severity 标记用例级别的使用
  • 使用Python实现智能食品市场预测的深度学习模型
  • python语言基础-5 进阶语法-5.2 装饰器-5.2.5 装饰器使用案例(自定义装饰器实现方法重载)
  • 【青牛科技】视频监控器应用
  • CSV 文件读取
  • 机器学习的全面解析:从基础到应用
  • # JVM学习
  • 基于YOLOv8深度学习的婴儿情绪状态检测系统(PyQt5界面+数据集+训练代码)
  • Ubuntu20.04 Rk3588 交叉编译ffmpeg7.0
  • 疫情下的图书馆管理系统:Spring Boot实现
  • 【MCU】GD32H7定时器使用外部时钟源
  • 01 IP路由基础
  • 集群聊天服务器(13)redis环境安装和发布订阅命令
  • 电子应用设计方案-13:智能消毒柜系统方案设计
  • 【LangChain】LangChain框架快速入门
  • html本地离线引入vant和vue2(详细步骤)
  • 《Python制作动态爱心粒子特效》
  • 【C语言】操作符2(含操作符的应用)
  • 小学知识相关链接