Java 并发编程-线程基础

本文详细介绍了Java中的线程相关概念,包括线程与进程的关系、线程上下文切换、线程优先级和线程状态。讲解了Java线程的创建方法,如继承Thread、实现Runnable接口和使用Callable+FutrueTask。此外,还探讨了线程的启动(start与run的区别)、线程等待与通知(wait、notify和notifyAll)、线程的中断以及用户线程和守护线程的区别。最后提到了Java线程管理工具,如jps、jstack和jconsole。
摘要由CSDN通过智能技术生成

1. 线程相关概念

1.1 线程和进程的关系

  1. 构成关系上看,线程是进程中的一个实体,一个进程中至少有一个线程,线程本身不能独立存在。

  2. 程序角度来看,进程是代码在数据集合上的一次运行活动,线程是进程的一个执行路径。

  3. 从操作系统资源分配上看,进程是系统进行资源分配和调度的基本单位,线程是CPU分配的基本单位。

  4. 资源访问的角度上看,多个线程共享进程的堆和方法区资源,但是每个线程有自己的程序计数器和栈区域。如下图所示

1.2 线程上下文切换

  • CPU通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务。但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这 个任务的状态。所以任务从保存到再加载的过程就是一次上下文切换。

  • JVM 使用程序计数器来记住下一条指令的执行地址,是线程私有的

  • 线程上下文频繁切换会影响性能,所以不是线程越多越好。这也是为什么在cpu核心数量只有一个的系统上,并发的效果甚至不如串行。


1.3 线程优先级

  • 现代操作系统基本采用时分的形式调度运行的线程,操作系统会分出一个个时间片,线程会分配到若干时间片,当线程的时间片用完了就会发生线程调度,并等待着下次分配。线程分配到的时间片多少也就决定了线程使用处理器资源的多少,而线程优先级就是决定线程需 要多或者少分配一些处理器资源的线程属性。

  • Java 中 Thread 对象有一个整形变量 priority 来控制优先级,可以通过 setPriority() 来设置这个值, 但是 Java 中线程优先级的设置效果不明显,操作系统可能会忽略这个线程优先级的设置.


1.4 线程状态

1.4.1 操作系统线程状态(五种)

状态名称 说明
初始状态 仅在语言层面创建了线程对象,还未与操作系统线程关联
可运行状态 指该线程已经被创建(与操作系统线程关联),可以由CPU调度执行
运行状态 指获取了CPU时间片运行中的状态
阻塞状态 如果调用了阻塞API,这时线程实际不会用到CPU,会导致上下文切换,进入阻塞状态。等操作完毕,由操作系统唤醒阻塞的线程,转换至可运行状态
终止状态 表示线程已经执行完毕,生命周期已经结束,不会转化为其他状态

(图片源自网络)

1.4.2 Java线程状态(六种)

根据 Thread.State 枚举,分为六种状态

状态名称 说明
NEW 初始状态,线程被构建,但是还没有调用start() 方法
RUNNABLE 运行状态,Java 线程将操作系统中的就绪、运行、阻塞三种状态笼统地称作“运行中”
BLOCKED 阻塞状态,表示线程阻塞于锁
WAITING 等待状态,表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知和中断)
TIME_WAITING 超时等待状态,该状态不同于WAITING,它是可以在指定的时间自行返回的
TERMINATED 终止状态,表示当前线程已经执行完毕

Java线程状态变迁

(图片来自《Java并发编程的艺术》)


1.5 线程死锁

  • 四个必要条件:互斥条件,请求并持有条件,不可剥夺条件,环路等待条件。
  • 避免死锁只需要破环至少一个必要条件,目前只有请求并持有和环路等待条件可以被破环。
  • 资源申请的有序性原则可以避免死锁。

2.创建线程的三种方法

2.1 方法一:继承 Thread ,重写 run 方法

public class ThreadTest1 {
   
    
    // 继承 Thread 并重写 run 方法
    public static class MyThread extends Thread {
   
        @Override
        public void run() {
   
            System.out.println("t1 run");
        }
    }

    public static void main(String[] args) {
   
        // 创建线程
        MyThread thread = new MyThread();
        // 启动线程
        thread.start()
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值