0%

java多线程--基本概念

线程概述

线程和进程

  • 进程:程序的一次执行过程,程序的运行就是一个进程从创建、运行到消亡的过程。进程是计算机运行的基本单位,进程之间是相互独立的。
  • 线程:线程是 CPU 执行的基本单位,一个进程可以分为多个线程,多个线程对进程的资源使用存在竞争关系。

线程的状态

  • 创建:线程 new 之后进入创建状态,调用 start() 方法进入就绪状态。
  • 就绪:线程就绪状态需要等待 CPU 调用执行
  • 运行:线程获取了 CPU 时间,进入运行中状态
  • 等待:wait、join、LockSupport.park 进入等待状态,需要其他线程通知才能进入运行状态 (notify、notifyAll、LockSupport.unPark)
  • 超时等待:在等待的基础上加了一个超时时间,超时时间到了就自动进入运行状态(sleep,wait(long),LockSupport.pariUntil,LockSupport.parkNanos)
  • 阻塞:线程调用同步方法或者代码块,未获得锁时,进入阻塞状态
  • 终止:线程执行完 run 方法后进入终止状态

并行和并发

  • 并行:多个处理器上,执行多个任务
  • 并发:单个处理器上,多个任务交替执行。线程通过轮询获取 CPU 的执行时间。

线程死锁

  • 多个线程同时被阻塞,他们中的一个或者多个都在等待某个资源被释放。由于无限期的阻塞,线程无法正常终止。

线程死锁的四个必要条件

  • 互斥条件:某一个资源某一时刻只能有一个线程使用
  • 请求和保持条件:一个线程在请求其他资源的时候,对其中持有的资源不释放
  • 不可剥夺条件:线程已获得的资源在未使用的情况下不能被其他线程强行剥夺,只能由该线程使用完毕后自己释放
  • 循环等待条件:多个线程形成的一种首位相接的等待资源的关系。

避免死锁

  • 破坏线程死锁产生的四个条件之一

    • 破坏互斥条件:这个条件我们没法破坏,因为我们用锁本来就是想让他们互斥(临界资源需要互斥访问)
    • 破坏请求和保持条件:一次性申请所有的资源。
    • 破坏不可剥夺条件:占用部分资源的现场进一步申请其他资源时,如果申请不到,可以主动释放他自己占有的资源。
    • 破坏循环等待条件:靠按序申请资源来预防,按某一顺序申请资源,释放资源则反序释放。

sleep和yeild方法

  • sleep方法在超时等待一定时间后会自动唤醒,进入就绪状态;yield方法是当前线程进入就绪状态线程调
  • sleep方法后,无论其他线程的优先级都有机会运行;执行yield方法,只会给相同优先级或更高优先级的方法的线程运行的机会
  • sleep方法会抛出InterruptedException异常,而yield方法没有任何异常声明
  • 循环中调用yield方法,yield死循环:线程yield之后有获得了cpu,导致其他线程无法获取资源

调用start方法,为什么不直接调用run方法

  • 调用 start 方法方可启动线程并使线程进入就绪状态,
  • 而 run 方法只是 thread 的一个普通方法调用,还是在主线程里执行。

线程创建的方式

  • 继承Thread类
  • 实现Runable接口,实现run方法
  • 实现Callable接口,实现call方法
  • 使用线程池

----------- 本文结束啦感谢您阅读 -----------