多线程

多线程

  • 创建方式

  • 线程调度优先

    线程是程序执行的最小单元,是程序中一个单一的顺序控制流程。线程是进程中的一个实体,是被系统独立调度和分派的基本单位 。假如我们的计算机只有一个 CPU,那么 CPU 在某一个时刻只能执行一条指令,线程只有得到 CPU时间片,也就是使用权,才可以执行指令。

    Java中对线程的调用方式有以下两种:

    • 分时调度模型 : 所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间片
    • 抢占式调度模型 :优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的 CPU 时间片相对多一些。
  • 多线程可能会导致共享数据的安全问题,因此为解决并发情况下的数据安全问题,需要引入锁机制

  • synchronized锁
    • 是基于JVM层面的锁
      • 锁代码块:本质是使用monitorenter和monitorexit指令来指向同步代码块开始的位置和技术的位置。当执行monitorenter指令时,试图获取monitor的持有权。当计数器为0时,可以成功获取,获取后计数器加一,其他线程将无法获取该代码块的执行权。
      • 锁方法:使用ACC_SYCHRONIZED表示来指明该方法是一个同步方法,JVM识别该表示后,执行相应的同步调用。
    • 使用场景
      • 单例模式
      • 生产者消费者模型
    • synchronized与volatile的异同
      • volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。
      • 多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞
      • volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。 volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性。
  • Reentrant Lock锁
    • 是基于API层面的锁
线程池

随着线程数目的增加,每次创建和销毁线程都要消耗一定的资源和时间,因此JAVA使用线程池来实现对多线程的维护、限制和管理

  • 使用线程池的好处

    • 降低资源消耗。 通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
    • 提高响应速度。 当任务到达时,任务可以不需要的等到线程创建就能立即执行。
    • 提高线程的可管理性。 线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
  • 创建线程池的方法

    • newSingleThreadExecutor:创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。

    • newFixedThreadPool:创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。

    • newCachedThreadPool:创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。

    • newScheduledThreadPool:创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。

    • newSingleThreadExecutor:创建一个单线程的线程池。此线程池支持定时以及周期性执行任务的需求。

  • Runnable和Callable接口的区别

    两者的区别在于 Runnable 接口不会返回结果但是 Callable 接口可以返回结果。

  • 执行execute()和submit()方法的区别

    • submit是ExecutorService中的方法 用以提交一个任务,他的返回值是future对象,可以获取执行结果

    • execute是Executor接口的方法,他虽然也可以像submit那样让一个任务执行 但并不能有返回值

  • future对象

    Future就是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果。

    必要时可以通过get方法获取执行结果,该方法会阻塞直到任务返回结果。

    也就是说Future提供了三种功能:

    • 判断任务是否完成;

    • 能够中断任务;

    • 能够获取任务执行结果。

  • 示例代码

    https://www.cnblogs.com/GarfieldEr007/p/10230865.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值