• [Java并发编程之美]第1章 线程基础


    第1章 线程

    1.1 线程与进程

    • 进程是操作系统资源分配和调度的基本单位,但cpu资源是分配到线程的,也就是线程是CPU分配的基本单位。
    • 线程自己的栈资源中,存放的局部变量是线程私有的,其他线程无法访问,除此之外栈还存线程的调用栈帧。

    1.2 线程创建

    三种方式:实现Runnable接口的run方法;继承Thread类并重写run方法;使用FutureTask方式。

    1.3 线程等待与通知(等待与通知的方法都在Object类中提供)

    等待
    • wait()
      线程先要事先获得共享变量上的监视器锁,然后当一个线程调用一个共享变量的wait()方法,该线程会被阻塞挂起,并且释放掉共享变量上的锁。直到发生:(1)此后其他线程调用了该共享对象的notify或notifyAll()方法 (2)此后其他线程调用了该线程的interrupt()方法。(该线程会抛出InterruptedException异常返回)

    • wait(long timeout)
      超时参数timeout:如果该线程调用wait(long timeout)挂起后,(过了timeout ms时间仍未被唤醒,) 该函数会因为等待时间超时返回。
      wait()内部就是调用了wait(0),两者相当。

    • wait(long timeout,int nanos)

    通知
    • notify()
      一个线程调用共享对象的notify()方法后,会唤醒有一个在该变量上调用wait系列方法后被挂起的线程,具体唤醒哪个线程是随机的。
      此外,被唤醒的线程不能马上从wait方法返回并继续执行,它必须在获取了共享对象的监视器锁后才可以返回。

    • notifyAll()
      notifyAll()方法会唤醒所有在该共享变量上由于调用wait系列方法而被挂起的线程(条件是必须是在notifyAll之前调用了wait系列方法而被挂起的线程)。

    1.4 等待线程执行终止的join方法(Thread类提供)

    join方法适用于等待某几件事情完成后才继续往下执行的情景。具体地,线程A调用线程B的join方法会被阻塞,等待线程B执行完毕返回。

    1.5 让线程睡眠的sleep方法(Thread类提供的静态方法)

    调用线程会暂时让出指定时间的执行权,也就是在这期间不参与CPU调度,但是该线程所拥有的监视器资源,比如锁还是持有不让出的。

    1.6 让出CPU执行权的yield方法(Thread类提供的静态方法)

    • 当一个线程调用yield方法,当前线程会让出CPU使用权,然后处于就绪状态,线程调度器会从线程就绪队列里面获取一个线程优先级最高的线程,当然也有可能会调度到刚刚让出CPU的那个线程来获取CPU执行权。
    • yield与sleep方法的区别在于,调用yield方法,线程只是让出自己剩余的时间片,并没有被阻塞挂起,而是处于就绪状态,线程调度器下一次调度时也有可能调度到当前线程执行。而sleep是当前调用线程被阻塞挂起指定时间。
    • yield方法很少被使用。一般用于调试时复现由于并发竞争条件导致的问题,或用来设计并发控制。

    1.7 线程中断

    • 1 置中断标志:void interrupt()方法
      调用线程A的interrupt()方法:设置线程A的中断标志为true。
      注意,只是设置了标志,但线程A并没有被中断,会继续往下执行。
      如果线程A正处于调用了wait()或join()或sleep()而被阻塞挂起的状态,而线程B调用了线程A的interrupt方法,线程A会直接抛出InterruptedException异常。

    • 2 查看中断标志

      • 法1 boolean isInterrupted()方法
        检测调用的线程实例对象是否被中断,不清除中断标志。
      • 法2 boolean interruputed()方法
        静态方法,检测当前语句所在线程是否被中断,清除中断标志。
      • 使用场景1:用来作为线程终止的条件,判断若中断标志为true,则线程终止。
      • 使用场景2:使阻塞挂起的线程提前终止。

    1.8 线程上下文切换

    • CPU资源的分配采用了时间片轮转的方式。上下文切换就是保存当前线程的执行现场,恢复下一个线程的执行现场。
    • 上下文切换发生场景:1 当前线程的CPU时间片使用完处于就绪态。2 当前线程被其他线程中断。

    1.9 线程死锁

    • 死锁:两个或两个以上线程在执行过程中,因争夺资源造成互相等待的现象。
    • 产生死锁必须具备的四个条件:1 互斥 2 请求并持有 3 不可剥夺 4 环路等待
    • 避免死锁:有序申请资源

    1.10 守护(daemon)线程与用户(user)线程

    • 守护线程与用户线程:当最后一个非守护线程退出时,JVM会正常退出。即守护线程是否结束并不影响JVM的退出。
      所以如果希望主线程结束后JVM马上结束,创建子线程时可以将其设置为守护线程;反之设置子线程为用户线程。
    • 例子:守护线程:垃圾回收线程;用户线程:main函数所在的线程。
    • 设置线程为守护线程:thread.setDaemon(true);
  • 相关阅读:
    yarn-cli 缓存
    html DOM 的继承关系
    JavaScript basics: 2 ways to get child elements with JavaScript
    svn merge 的区别
    virtualbox 设置windows 于ubuntu虚拟机共享文件夹
    angular 学习理解笔记
    e.which
    痛定思痛
    【转】反思 成长
    日语学习词汇量
  • 原文地址:https://www.cnblogs.com/coding-gaga/p/11291532.html
Copyright © 2020-2023  润新知