• java多线程小结


    一、并行 并发 和线程 进程

    1. 并行与并发

      • 并发:指两个或多个事件在同一个时间段内**发生。
      • 并行:指两个或多个事件在同一时刻发生(同时发生)。
    2. 线程 进程

      • 一个程序运行后至少有一个进程,一个进程中可以包含多个线程
    3. 线程调度:

      • 分时调度

        所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。

      • 抢占式调度

        优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。

        • 设置线程的优先级

    二、多线程

    1. 原理:

      • 多线程执行时,在栈内存中,其实每一个执行线程都有一片自己所属的栈内存空间。进行方法的压栈和弹栈
      • 当执行线程的任务结束了,线程自动在栈内存中释放了。但是当所有的执行线程都结束了,那么进程就结束了
    2. Thread类:

      1. 构造方法:
        • public Thread() :分配一个新的线程对象。
        • public Thread(String name) :分配一个指定名字的新的线程对象。
        • public Thread(Runnable target) :分配一个带有指定目标新的线程对象。
        • public Thread(Runnable target,String name) :分配一个带有指定目标新的线程对象并指定名字。
      2. 常用方法:
        • public String getName() :获取当前线程名称。
        • public void start() :导致此线程开始执行; Java虚拟机调用此线程的run方法。
        • public void run() :此线程要执行的任务在此处定义代码。
        • public static void sleep(long millis) :使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行)。
        • public static Thread currentThread() :返回对当前正在执行的线程对象的引用。
    3. Runnable类

      Runnable对象仅仅作为Thread对象的target,

      Runnable实现类里包含的run()方法仅作为线程执行体。

      ** 而实际的线程对象依然是Thread实例,只是该Thread线程负责执行其target的run()方法**

    4. Thread类和Runnable类的区别(实现Runnable接口比继承Thread类所具有的优势)

      1. 适合多个相同的程序代码的线程去共享同一个资源。
      2. 可以避免java中的单继承的局限性。
      3. 增加程序的健壮性,实现解耦操作,代码可以被多个线程共享,代码和线程独立。
      4. 线程池只能放入实现Runable或Callable类线程,不能直接放入继承Thread的类。
    5. 拓展:

      在java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。每当使用 java命令执行一个类的时候,实际上都会启动一个JVM,每一个JVM其实在就是在操作系统中启动了一个进程

    三、线程安全

    线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写 操作,一般来说,这个全局变量是线程安全的;若有多个线程同时执行写操作,一般都需要考虑线程同步, 否则的话就可能影响线程安全

    线程同步:

    1. 同步代码块: synchronized 关键字可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问

      • 格式:
      synchronized(同步锁){
      	需要同步操作的代码
      }
      
      • 同步锁:
        • 在任何时候,最多允许一个线程拥有同步锁,谁拿到锁就进入代码块,其他的线程只能在外等着 (BLOCKED)
        • 锁对象可以是任意类型
        • 多个线程对象要使用同一把锁
    2. 同步方法

      同步锁:

      • 对非静态方法,同步锁就是this
      • 对静态方法,使用当前方法所在类的字节码对象
    3. 锁机制(LOCK)

      public void lock() //加同步锁
      public void lock() //释放同步锁
      

      线程状态:

      当线程被创建并启动以后,它既不是一启动就进入了执行状态,也不是一直处于执行状态

      • NEW(新建)
      • Runnable(可运行)
      • Blocked(锁阻塞)
      • Waitting(无线等待)
      • Timed Waitting(计时等待)
      • Timinated(被终止)

      image-20200508192410088

    四、等待唤醒机制

    等待唤醒中的方法

    等待唤醒机制就是用于解决线程间通信的问题的,使用到的3个方法的含义如下:

    1. wait:线程不再活动,不再参与调度,进入 wait set 中,因此不会浪费 CPU 资源,也不会去竞争锁了,这时的线程状态即是 WAITING。它还要等着别的线程执行一个特别的动作,也即是“通知(notify)”在这个对象上等待的线程从wait set 中释放出来,重新进入到调度队列(ready queue)中
    2. notify:则选取所通知对象的 wait set 中的一个线程释放;例如,餐馆有空位置后,等候就餐最久的顾客最先入座。
    3. notifyAll:则释放所通知对象的 wait set 上的全部线程。

    注意:

    哪怕只通知了一个等待的线程,被通知线程也不能立即恢复执行,因为它当初中断的地方是在同步块内,而此刻它已经不持有锁,所以她需要再次尝试去获取锁(很可能面临其它线程的竞争),成功后才能在当初调用 wait 方法之后的地方恢复执行。

    总结如下:

    • 如果能获取锁,线程就从 WAITING 状态变成 RUNNABLE 状态;
    • 否则,从 wait set 出来,又进入 entry set,线程就从 WAITING 状态又变成 BLOCKED 状态

    调用wait和notify方法需要注意的细节

    1. wait方法与notify方法必须要由同一个锁对象调用。因为:对应的锁对象可以通过notify唤醒使用同一个锁对象调用的wait方法后的线程。
    2. wait方法与notify方法是属于Object类的方法的。因为:锁对象可以是任意对象,而任意对象的所属类都是继承了Object类的。
    3. wait方法与notify方法必须要在同步代码块或者是同步函数中使用。因为:必须要通过锁对象调用这2个方法。

    五、线程池

    1. 使用:

      Java里面线程池的顶级接口是java.util.concurrent.Executors,但是严格意义上讲Executors并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是java.util.concurrent.ExecutorService

    2. Executors类中有个创建线程池的方法如下:

      • public static ExecutorService newFixedThreadPool(int nThreads):返回线程池对象。(创建的是有界线程池,也就是池中的线程个数可以指定最大数量)

      获取到了一个线程池ExecutorService 对象,那么怎么使用呢,在这里定义了一个使用线程池对象的方法如下:

      • public Future<?> submit(Runnable task):获取线程池中的某一个线程对象,并执行

        Future接口:用来记录线程任务执行完毕后产生的结果。线程池创建与使用。

      使用线程池中线程对象的步骤:

      1. 创建线程池对象。
      2. 创建Runnable接口子类对象。(task)
      3. 提交Runnable接口子类对象。(take task)
      4. 关闭线程池(一般不做)。
  • 相关阅读:
    ncnn 编译配置
    Android 配置 ncnn
    Android Studio 配置 OpenCV4+
    ROS catkin cheat sheet
    CMake 使用代理服务器
    Git设置代理服务器
    安卓assets处理
    【Android】Toast on non-UI thread
    高级语言编译和运行系统
    linux环境安装包方式
  • 原文地址:https://www.cnblogs.com/zx-coder/p/12852574.html
Copyright © 2020-2023  润新知