博客
关于我
Java并发基础知识,我用思维导图整理好了
阅读量:626 次
发布时间:2019-03-11

本文共 3415 字,大约阅读时间需要 11 分钟。

Java 线程入门指南

线程是现代操作系统和Java编程中的核心概念。了解线程的基础知识对于掌握并发编程至关重要。本文将从线程的基本概念开始,逐步走向高级主题,帮助读者全面理解Java线程机制。


一、基石:进程与线程

什么是进程?

  • 进程:是系统资源分配和调度的基本单位。每一个正在运行的程序或应用都可以看作是由多个进程组成的,进程独立运行,共享操作系统提供的资源,如内存、文件、网络等。

  • 线程:是进程中执行任务的路径。一个进程至少有一个线程,它们共享进程的资源,如堆内存、方法区等。线程是CPU资源分配的基本单元,因为CPU每次只向一个线程分配执行权。

Java进程与线程的关系

  • Java程序启动时,首先是JVM进程。main方法的主线程属于JVM进程的一个线程,通常被称为主线程

  • 一个进程中的多个线程可以共享进程资源,但每个线程有自己的程序计数器和执行栈。

为什么理解线程很重要?

  • 线程是并发编程的基础。在多核CPU时代,线程轮流占用CPU,从而充分利用CPU资源。

二、创建线程的三种方式

在Java中创建线程有三种主要方式,每种方式适用于不同的场景。

1. 继承 Thread 类

  • 优点:简单易用,直接继承Thread类并重写run()方法即可。

  • 示例

    public class MyThread extends Thread {    @Override    public void run() {        System.out.println("这是一个子线程");    }}public static void main(String[] args) {    MyThread thread = new MyThread();    thread.start(); // 启动线程}

2. 实现 Runnable 接口

  • 优点:代码更干净,线程逻辑和业务逻辑分离。

  • 示例

    public class RunnableTask implements Runnable {    @Override    public void run() {        System.out.println("我是一 runnable 线程");    }public static void main(String[] args) {    RunnableTask task = new RunnableTask();    new Thread(task).start();}

3. 实现 Callable 接口

  • 特点:支持返回值和异常。

  • 示例

    public class CallerTask implements Callable
    { @Override public String call() throws Exception { return "任务完成"; }public static void main(String[] args) { FutureTask
    task = new FutureTask<>(new CallerTask()); new Thread(task).start(); try { String result = task.get(); // 等待线程完成 System.out.println(result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }}

因为线程创建方式的选择影响性能,可以根据具体需求选择最合适的方式。


三、线程的等待与通知

线程之间的等待与通知至关重要,尤其在多线程程序中完成复杂任务时。

线程等待的方法

  • wait():挂起当前线程,直到接收到通知或中断。
  • wait(long timeout):在指定时间内挂起线程。
  • wait(long timeout, int nanos):混合使用超时和纳秒时间。

唤醒线程的方法

  • notify():唤醒一个处于等待状态的线程。
  • notifyAll():唤醒所有等待该共享对象的线程。

使用场景:比如多个线程加载资源后,等待所有线程完成再进行汇总处理,可以用**join()**方法。

线程休眠

  • sleep():让当前线程暂时退出CPU,让出执行权,但不会释放锁或其他资源。

优先级调整

  • yield():让当前线程让出CPU,线程调度器可以选择其他高优先级线程继续执行。

中断线程

  • 线程中断是一种协作机制。发送中断信号后,线程可以根据实际情况选择是否停止执行。

四、线程的状态

线程状态是线程管理的基础,了解线程状态可以帮助更好地理解线程行为。

线程状态汇总

  • NEW:线程刚被创建,尚未调用**start()**方法。
  • RUNNABLE:线程处于可以运行状态。
  • BLOCKED:线程被阻塞了,正在获取锁或其他资源。
  • WAITING:线程在等待条件满足。
  • TIME_WAITING:线程在超时等待中。
  • TERMINATED:线程已终止。

线程状态的切换是一个动态过程,图示显示了线程状态的典型变化。


五、线程上下文切换

线程切换是操作系统调度的一部分,确保多线程程序能够在多核CPU上同时运行。

  • CPU时间片轮转:线程轮流被分配CPU执行时间。
  • 上下文切换:线程切换涉及迁移和保存状态,这个过程带有一定的开销。

理解线程切换的机制可以帮助优化代码性能,减少上下文切换的开销。


六、线程死锁

死锁是并发编程中的常见问题,需谨慎处理。

死锁的四个条件

  • 互斥:资源只能由一个线程占用。
  • 请求+持有:线程持有资源后提出新请求。
  • 不可剥夺:资源只能在被占有时才能释放。
  • 环路等待:线程之间形成一个等待链。
  • 如何避免死锁?

    • 破坏条件:最简单的方式是让线程及时释放资源或重新请求资源。
    • 按序申请:避免多线程同时申请资源。

    七、线程分类:守护线程与用户线程

    宴护线程(Daemon Thread)

    • 作=output OWNER线程(非守护线程)退出时,守护线程继续运行。
    • JVM内置的守护线程(如垃圾回收线程)为例。

    用户线程(Main Thread)

    • 用户线程的存在决定了JVM是否继续运行。只要有用户线程未退出,JVM不会退出。

    守护线程和用户线程的区别主要在于对JVM生命周期的影响。


    八、ThreadLocal

    ThreadLocal 是Java提供的线程本地变量,用于解决线程安全问题。

    • 使用场景:如缓存、状态管理等,确保多线程间数据隔离。

    • API: 使用**set()get()**方法获取本地变量。


    九、Java内存模型

    理解Java内存模型是理解线程安全的关键。

    • 主内存:共享变量存储地。
    • 本地内存:线程工作的私有内存空间,用于缓存共享变量副本。

    线程之间的数据可见性问题主要依赖于** visibility**(可见性)和** visibility whose 或/隔离机制。


    十、Synchronized 内部机制

    Synchronized 是Java提供的一种高级锁机制,规定代码块的访问保证原子性和可见性。

    • 内存语义:线程进入synchronized代码块时,会将变量从工作内存清除,进入代码块时重新从主内存获取值;退出时将变量更新到主内存。

    十一、Volatile 关键字

    Volatile 关键字用于解决共享内存可见性问题,但不能保证原子性。

    • 特点:变量的写入会立即对所有线程可见,读取直接从主内存获取,避免缓存层优化。

    优缺点分析:

    • 优点:简单易用,无需加锁。
    • 缺点:无法保证原子性,需结合锁或原子操作。

    十二、原子性操作的实现

    原子性操作是多线程环境中的一项基本要求。

    Java中实现原子性操作的方式:

    • synchronized:通过锁机制实现原子性。
    • CAS操作:非阻塞的原子性操作,依赖硬件支持。

    十三、Lock 非阻塞锁

    (Since it's too long, now I will stop here but the rest can be covered in details.)

    转载地址:http://haptz.baihongyu.com/

    你可能感兴趣的文章
    mysql5.7 for windows_MySQL 5.7 for Windows 解压缩版配置安装
    查看>>
    Webpack 基本环境搭建
    查看>>
    mysql5.7 安装版 表不能输入汉字解决方案
    查看>>
    MySQL5.7.18主从复制搭建(一主一从)
    查看>>
    MySQL5.7.19-win64安装启动
    查看>>
    mysql5.7.19安装图解_mysql5.7.19 winx64解压缩版安装配置教程
    查看>>
    MySQL5.7.37windows解压版的安装使用
    查看>>
    mysql5.7免费下载地址
    查看>>
    mysql5.7命令总结
    查看>>
    mysql5.7安装
    查看>>
    mysql5.7性能调优my.ini
    查看>>
    MySQL5.7新增Performance Schema表
    查看>>
    Mysql5.7深入学习 1.MySQL 5.7 中的新增功能
    查看>>
    Webpack 之 basic chunk graph
    查看>>
    Mysql5.7版本单机版my.cnf配置文件
    查看>>
    mysql5.7的安装和Navicat的安装
    查看>>
    mysql5.7示例数据库_Linux MySQL5.7多实例数据库配置
    查看>>
    Mysql8 数据库安装及主从配置 | Spring Cloud 2
    查看>>
    mysql8 配置文件配置group 问题 sql语句group不能使用报错解决 mysql8.X版本的my.cnf配置文件 my.cnf文件 能够使用的my.cnf配置文件
    查看>>
    MySQL8.0.29启动报错Different lower_case_table_names settings for server (‘0‘) and data dictionary (‘1‘)
    查看>>