多线程知识点

线程从创建到死亡的状态
  1. 新建(new):新创建了一个线程对象。

  2. 可运行(runabble):线程对象创建后,其他线程(比如main线程)调用了该对象的start() 方法。

    该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu的使用权。

  3. 运行(runnning):可运行状态(runnable)的线程获得了cpu时间片(timeslice),执行程序代码。

  4. 阻塞(block):阻塞状态是指线程因为某种原因放弃了cpu的使用权,即让出了 cpu timeskice,暂时停止运行。直到线程进入可运行状态(runnable)状态,才有机会再次获取 cpu timeslice 转到 运行(running)状态。

    • 阻塞分三种情况
      1. 等待阻塞:运行(running)的线程执行了 object.wait()方法,JVM会吧该线程放入等待队列(waitting queue)中。
      2. 同步阻塞:运行(running)的线程在获取对象的同步锁是,若该同步锁被别的线程占用,则JVM会吧该线程放入锁池(lock pool)中。
      3. 其他阻塞:运行(running)的线程执行 Thread.sleep(long ms)或者Thread.join()方法,或者发出了 I/O 请求时,JVM会吧该想爱你成设置为阻塞状态。当 sleep() 超时时、join() 等待线程终止或者超时、或者 I/O 处理完毕时,线程重新转入可运行(runabble)状态。
  5. 死亡(dead):线程run(),main()方法执行结束,或者因为异常退出了 run() 方法,则该线程结束生命周期。死亡的想爱你成不可再次复生。

同步、异步
  • 同步:线程T1强依赖于线程T2,T1向T2发了一个请求,T1必须等到T2的回复才能继续自己的操作,若T2迟迟不响应,则T1就一直处于等待(阻塞状态)
  • 异步:与同步相反,T1向T2发送了一个请求,不管T2是否有响应,都不妨碍T1的正常运行。
线程同步方法
  • wait():使线程变成阻塞状态,释放锁。Object类方法,在对某对象使用了此方法之后,只有再对此对象使用notify() 或者 notifyall()方法,才能使此对象转为就绪状态,获得对象锁,即可进入运行状态
  • sleep():Thread类方法,暂时使线程转为阻塞状态,不过,不释放锁。导致线程暂停执行指定时间,把执行机会让给其他线程,监控状态依旧保持,到时间后会自动激活。
  • notify():随机使一个阻塞线程转为就绪状态,具体激活哪个线程,由JVM确定,不是按优先级确定
  • notifyall():激活所有阻塞线程,至于哪个线程可以运行,需要看他们争抢资源的能力了。
线程池的种类、优势、运行流程
  1. newCachedThreadPool:创建一个可缓存线程池,如果线程池长度(最大数量,Interger.MAX_VALUE)超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
  2. newFixedThreadPool:创建一个定长线程池,可控制线程最大并发数,超出的线程会在池队列中等待。
  3. newScheduledThreadPool:创建一个定长线程池,支持定时及周期性任务执行。
  4. newSingleThreadExecutor::创建一个单线程化的线程池,他只会用唯一的工作线程来执行任务,保证所有任务按指定顺序(FIFO,LIFO,优先级)执行。并且在任意给定的时间不会有多个线程是活动的 。
  • 优势

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

    • 线程池参数说明:

      1. corePoolSize(线程池的基本线程数)
      2. maximumPoolSize(线程池最大线程数)
      3. keepAliveTime(线程活动保持时间)
      4. TimeUnit(线程活动保持时间的单位)
      5. workQueue(任务队列)
        • ArrayBlockingQueue:基于数组结构的游街阻塞队列,FIFO排序
        • LinkedBlockingQueue:基于链表的阻塞队列,按FIFO对元素排序(吞吐量通常要高于ArrayBlockingQueue)。静态工厂方法Executors.newFixedThreadPool()使用了这个队列。
        • SynchronousQueue:不存储元素的阻塞队列。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkBlockingQueue,静态工厂方法Executors.newCachedThreadPool使用了这个队列。
        • PriorityBlockingQueue:具有优先级的无线阻塞队列
      6. ThreadFactory:用于设置创建线程的工厂,可以设置名字
      7. RejectedExecutionHandler:(饱和策略)当队列和线程池都满了,说明线程池处于饱和状态,必须采用一种策略处理新任务时抛出异常
        • JDK1.5提供的四种策略
          1. AbortPolicy:直接抛出异常
          2. CallerRunsPolicy:只用调用者所在线程来运行任务
          3. DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务
          4. DiscardPolicy:不处理,直接丢弃。
          5. 当然也可以根据应用场景来实现 RejectedExecutionHandler 接口自定义策略。比如:记录日志或持久化不能处理的任务。
    • 当提交一个新任务到线程池时,线程池的处理流程如下:

[外链图片转存失败(img-sssACCEt-1565752889832)(images/ThreadPool.png)]

	1. 首先线程池判断 核心线程池(corePoolSize)是否已满?
   - 没满:创建一个核心线程去处理任务
   - 满了:任务被放进任务队列workQueue排队等待执行
	2. 其次判断等待队列workQueue是都已满?
 - 没满:任务被放进任务队列workQueue排队等待执行
 - 满了:判断整个线程池的线程数是否达到了maximumPoolSize
	3. 判断整个线程池的线程数是否达到了maximumPoolSize?
 - 未达到:创建非核心线程执行任务
 - 达到了:根据饱和策略拒绝该任务。
AQS
  • 实现锁的框架
  • 内部实现的关键:FIFO队列,state状态。
  • 定义了内部类 ConditionObject
  • 拥有两种线程模式:独占模式和共享模式
synchronized 和 java.util.concurrent.locks.Lock 的异同
  • 同:Lock 可以完成 synchronized 的所有功能

  • 不同:Lock 有比 synchronized 更精确的线程语义和更好的性能。synchronized 后自动的释放锁,而 Lock是显式加锁,并且必须在finally从句中释放锁

如何确保N个线程可以访问N个资源,但同时又不导致死锁?
  • 一种简单的避免死锁的方式就是:指定获取锁的顺序,并强制线程按照指定顺序获取锁。因此,如果所有的线程都是以同样的顺序加锁和释放锁,就不会出现死锁了。

  • 死锁产生的四个条件:

    1. 互斥条件:一个资源每次只能被一个进程使用。
    2. 占有且等待:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
    3. 不可强行占有:进程已获得的资源,在未使用完之前,不能强行剥夺。
    4. 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。、
  • 这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,然而只要上述条件之一不满足,就不会发生死锁。

  • 处理死锁的基本方法:

    1. 死锁预防:通过设置某些限制条件,去破坏死锁的四个条件中的一个或几个条件,来预防发生死锁。(但由于所施加的限制条件往往太严格,因而导致系统资源利用率和系统吞吐量降低)
    2. 死锁避免:允许前三个必要条件,但通过一定的选择,确保永远不会到达死锁点,因此死锁避免比死锁预防允许更多的并发。
    3. 死锁检测:不采用任何限制性措施,允许系统在运行过程中发生死锁,但可通过设置的检测机构及时检测死锁的发生,并精确的确定死锁相关的进程和资源,然后采取是适当的措施,从系统中将已发生的死锁清除掉。
    4. 死锁解除:与死锁检测配套的一种措施。当检测到系统中已发生死锁,需将进程从思索状态中解脱出来。
      • 常用方法:撤销或挂起一些进程,以便回收一些资源,再将这些资源分配给已处于阻塞状态的进程。死锁检测和解除有可能使系统获得较好的资源利用率和吞吐率,但在实现上难度也最大。
  • **死锁预防:**破坏死锁的四个条件中的一个或几个

    1. 互斥:它是设备固有的属性所决定的,不仅不能改变,还应该加以保证。
    2. 占有且等待:为预防占有且等待条件,可以要求进程一次性的请求所有需要的资源,并且阻塞这个进程直到所有请求都同时满足。这个方法比较低效。
    3. 不可强行占有:预防方法:
      • 如果一个进程请求当前被另一个进程占有的一个资源,则操作系统可以抢占另外一个进程,要求它释放资源。
      • 如果占有某些资源的一个进程进行进一步的资源请求被拒绝是,则该进程必须释放它最初占有的资源。
    4. 循环等待:通过定义资源类型的线性顺序来访问。如果一个进程已经分配了R类资源,那么接下来请求的资源只能是那些排在R类型之后的资源类型。该方法比较低效。
  • **死锁避免:**允许前三个条件,

    • 两种死锁避免算法:
      1. 进程启动拒绝:如果一个进程的请求会导致死锁,则不启动该进程。
      2. 资源分配拒绝:如果一个进程增加的资源请求会导致死锁,则不允许此分配(银行家算法)
  • 死锁检测和解除

    • 死锁解除算法:剥夺资源和撤销进程。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数字乡村和智慧农业的数字化转型是当前农业发展的新趋势,旨在通过应用数字技术,实现农业全流程的再造和全生命周期的管理服务。中国政府高度重视这一领域的发展,提出“数字中国”和“乡村振兴”战略,以提升国家治理能力,推动城乡融合发展。 数字乡村的建设面临乡村治理、基础设施、产业链条和公共服务等方面的问题,需要分阶段实施《数字乡村发展战略纲要》来解决。农业数字化转型的需求包括满足市民对优质农产品的需求、解决产销对接问题、形成优质优价机制、提高农业劳动力素质、打破信息孤岛、提高农业政策服务的精准度和有效性,以及解决农业融资难的问题。 数字乡村建设的关键在于构建“1+3+4+1”工程,即以新技术、新要素、新商业、新农民、新文化、新农村为核心,推进数据融合,强化农业大数据的汇集功能。数字农业大数据解决方案以农业数字底图和数据资源为基础,通过可视化监管,实现区域农业的全面数字化管理。 数字农业大数据架构基于大数据、区块链、GIS和物联网技术,构建农业大数据中心、农业物联网平台和农村综合服务指挥决策平台三大基础平台。农业大数据中心汇聚各类涉农信息资源和业务数据,支持大数据应用。信息采集系统覆盖市、县、乡、村多级,形成高效的农业大数据信息采集体系。 农业物联网平台包括环境监测系统、视频监控系统、预警预报系统和智能控制系统,通过收集和监测数据,实现对农业环境和生产过程的智能化管理。综合服务指挥决策平台利用数据分析和GIS技术,为农业决策提供支持。 数字乡村建设包括三大服务平台:治理服务平台、民生服务平台和产业服务平台。治理服务平台通过大数据和AI技术,实现乡村治理的数字化;民生服务平台利用互联网技术,提供各类民生服务;产业服务平台融合政企关系,支持农业产业发展。 数字乡村的应用场景广泛,包括农业生产过程、农产品流通、农业管理和农村社会服务。农业生产管理系统利用AIoT技术,实现农业生产的标准化和智能化。农产品智慧流通管理系统和溯源管理系统提高流通效率和产品追溯能力。智慧农业管理通过互联网+农业,提升农业管理的科学性和效率。农村社会服务则通过数字化手段,提高农村地区的公共服务水平。 总体而言,数字乡村和智慧农业的建设,不仅能够提升农业生产效率和管理水平,还能够促进农村地区的社会经济发展,实现城乡融合发展,是推动中国农业现代化的重要途径。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值