java线程 Thread 源码详解

线程

概述

  1. 进程:应用程序在内存中分配的空间,也就是运行中的程序,各个进程之间互不干扰,进程是操作系统进行资源分配的基本单位,单独占有内存地址空间和其他系统资源
  2. 线程: 线程是操作系统进行调度(cpu分配时间)的基本单位, 是在进程中执行的一个任务,共享所属进程的内存地址空间和资源

jvm层面线程状态

  • 以下状态为虚拟机线程状态,并不映射任何操作系统的线程状态
  1. 新建状态(NEW): 新创建的线程,还未调用start() 方法

  2. 可运行状态(RUNNABLE) : 调用了start() 方法,线程已经进入虚拟机,在等待操作系统的其他资源,如IO阻塞,网络阻塞,或者已经在运行中

  3. 阻塞状态(BLOCKED): 线程需要等待获取锁,等待进入同步(synchronized)方法或者同步块中, 或者说当因为获取不到锁而无法进入同步块时,线程处于 BLOCKED 状态

    1. 等待状态(WAITING): 当条件不满足时,等待其他线程完成操作使得条件满足,并通知等待中的线程,调用 Object.wait(), Thread.join(),LockSupport.park() 方法会使得线程进入等待状态。当一个线程调用Object.wait() 方法时,需要等待其他线程调用 Object.notify()/Object.notifyAll() 方法来唤醒, 当一个线程被 调用 LockSupport.park() 方法时,线程进入等待状态,需要对应的LockSupport.unPark(Thread)方法来唤醒指定的线程,或者通过interrupted() 方法中断线程使得线程继续执行,使得线程继续运行
  4. 限时等待(TIMED_WAITING): 等待指定的时间,调用Thread.sleepObject.wait(long)Thread.join(long)等方法会让线程进入该状态

  5. 结束状态(TERMINATED) : 线程执行完毕或者退出

    image

操作系统层面的线程状态

  • 操作系统层面的线程状态主要围绕cpu 操作
  1. new : 新建一个线程
  2. ready: 进入就绪状态,获得了除cpu 外的其他资源
  3. running : 运行状态, 线程已在cpu 上执行
  4. waiting : 等待状态,由于I/O ,或者其他等待事件,使得线程放弃cpu资源,从而进入等待状态,在这些事件完成后,线程会从新进入ready 状态,等待cpu资源的分配
  5. terminated : 线程执行完成

image

重要方法

  1. Object.wait

    • wait方法调用前需要获得锁, 应该总是在 循环中调用,即条件判断应该放在循环的条件判断,而不是放在 if 的判断中,防止虚假幻想(幻想后任然不符合执行条件)

      synchronized (obj) {
             
          while (<condition does not hold>)
              obj.wait(timeout);
          ... // Perform action appropriate to condition
      }
      
    • wait 方法必须在同步方法或者同步块中synchronized ,即要先获取锁才能调用wait 方法,这是第一次enter

    • 当前线程调用 wait方法后会释放 锁,当前线程进入该锁的 等待队列中,当前线程进入等待状态WAITING

    • 当收到其他线程的 notify 或者 notifyAll 通知后,当前线程并不能立即恢复执行,因为他已经释放了锁,所以要重新执行wait方法后的代码需要重新获取 锁,再次进入同步块中 这是第二次进入(reenter)

  2. Thread.join

    • 有线程a,b , 在线程 a 中调用 b.join , 相当与让 a线程等待 b线程的完成 , 此时a 停止执行, 等b执行完了,会通知a线程,使其恢复执行
  3. Thread.sleep

    • 经常会听到说 wait方法会释放锁, sleep 方法不会释放锁,其实这句话是不准确的,sleep 方法与锁无关,执行sleep 方法前并不是一定要获取锁(执行wait 方法前一定要先获取锁), 如果执行sleep 方法时没未获取锁,也就无所谓释放不释放,如果执行sleep 方法时已经获取了锁,则不会释放锁
  4. Thread.yield()

    • 中断当前线程的执行,让出cpu, 让自己和其他线程重新竞争cup 资源并运行
  5. LockSupport.park()

    • 使得当前线程停止执行进入等待状态,当调用LockSupport.unPark(Thread) 方法指定解锁该线程时,线程继续从中断处运行,或者该线程调用了interrupt()方法中断该线程时,也会使得线程结束等待状态,继续运行

      public class LockSupportTest {
             
          public static class ParkThread extends Thread{
             
              public ParkThread(String name) {
             
                  super(name);
              }
      
              @Override
              public void run() {
             
                  System.out.println(getName() + " running 00000000");
                  LockSupport.park();
                  if (Thread.currentThread
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值