




已阅读5页,还剩19页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
Java并发编程技术,欧阳宏基,本章内容,1.线程池的概念与工作原理2.Executor并发编程框架以及线程池执行策略3.Future与Callable4.线程锁5.利用Condition实现线程间通信6.阻塞队列,3,线程池的概念与工作原理,为什么使用线程池:假设在一台服务器完成一项任务的时间为TT1创建线程的时间T2在线程中执行任务的时间,包括线程间同步所需时间T3线程销毁的时间那么TT1T2T3。T1,T3是多线程本身的带来的开销,希望减少T1,T3所用的时间,从而减少T的时间。如果在程序中频繁的创建或销毁线程,这导致T1和T3在T中占有相当比例。显然这是突出了线程的弱点(T1,T3),而不是优点(并发性)。线程池技术正是关注如何缩短或调整T1,T3时间的技术,从而提高服务器程序性能的。它把T1,T3分别安排在服务器程序的启动和结束的时间段或者一些空闲的时间段,这样在服务器程序处理客户请求时,不会有T1,T3的开销了。,4,线程池的概念与组成部分,线程池:一种管理一定数量线程的手段,线程池中的线程数量是由运行时机器容量、负载的配置信息以及动态信息决定。应用程序在启动时创建一定数量的线程放入线程池,线程池通过将需要并发运行的任务放入到任务队列中等待空闲线程来处理。组成部分:(1)线程池管理器(ThreadPoolManager):用于创建并管理线程池(2)工作线程(WorkThread):线程池中线程(3)任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行。(4)任务队列:用于存放没有处理的任务。提供一种缓冲机制。,5,线程池的工作原理,创建线程池,要设计一个线程池至少要考虑以下几个方面:对任务进行描述的类,包含线程池中线程执行的所有信息。可动态变化的、保存任务的队列。线程池管理器,用来创建、销毁线程池,提供对任务的调用与转发。处理任务的工作线程类。查询线程,用来检测任务的完成情况。拒绝策略。自定义线程池还是具有相当大难度的,JDK自带的线程池,核心线程池对象-ThreadPoolExecutor,ThreadPoolExecutor是线程池体系中的核心类,用来创建和维护线程池对象。主要属性如下:corePoolSize:核心线程数量(包括空闲线程)maximumPoolsize:线程池中能创建的最大线程数keepAliveTime:当线程数大于核心数时,空闲线程被销毁前等待任务的最长时间unitkeepAliveTime:参数的时间单位workQueue:保存任务的队列,任务实现Runnable接口,由Execute方法调用执行threadFactory:创建线程对象所使用的工厂。handler:由于超出线程范围和队列容量而使执行任务被阻塞时采用的处理程序见源文件:ThreadPoolExecutorTest.java,线程池的执行策略,执行策略是一种资源管理方式,通过限制并发的数量来确保应用程序不会由于资源耗尽而失败。执行策略主要从执行任务的线程、任务的执行顺序、任务并发执行的个数、任务队列中等待执行的个数、对哪个任务进行拒绝并如何通知应用程序等方面来定义任务的执行,从而确保应用程序具有较好的性能。,线程池的执行策略,Executors通过工厂方法提供了四种执行策略来管理工作线程,分别是:newSingleThreadExecutor:确保所有任务按照提交的先后顺序由唯一工作线程来执行。newFixedThreadPool:线程数量是固定的,随着任务的提交而一一创建,直到数量达到最大值。newCachedThreadPool:一个可缓存的线程池,线程池大小完全依赖于操作系统(或者JVM)能够创建的最大线程数,并且能根据当前任务的数量来调整线程池中线程的个数,适合于执行生存周期较短的异步任务。见源文件:ThreadPoolTest.javanewScheduledThreadPool:创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。见源文件:ScheduledThreadPoolTest.java,Callable&Future,采用实现Runnable接口的线程无法取得返回值。Callable是接口,其中包含一个call方法,该方法具有返回值。实现Callable接口的类能够当做多线程中的任务类。Future类可以拿到Callable的返回值,Future的类型应该与Callable返回值类型一致。见源文件:callable/CallableAndFutureTest.java某些情况下,需要执行一组任务,哪个任务先完成,就先取哪个任务的值。这种情况下可以使用CompletionService。CompletionService将生产新的异步任务与使用已完成任务的结果分离开来的服务。生产者submit执行的任务。使用者take已完成的任务,并按照完成这些任务的顺序处理它们的结果。见源文件:callable/CompletionServiceTest.java,线程锁,传统实现线程同步的方法:(1)synchronized代码段(2)synchronized方法JDK1.5之后提供了线程锁技术来实现同步线程锁的特点:比传统线程技术中的synchronized关键字更加面向对象,在实现互斥(同步)的代码中,必须要获得相应的锁对象。上锁操作的相关代码出现在资源所在类的方法中,而不是线程代码中。见源文件:lock/LockTest.java见源文件:lock/BonusTest.java,线程锁,锁的分类:(1)读锁(2)写锁接口ReadWriteLock维护了一对相关的锁,一个用于只读操作,另一个用于写入操作。如果只进行读操作,那么多个线程可以对同一个共享资源加多次读锁。写入锁是独占的,用在对共享资源进行修改的情况下。多个线程要同时进行修改操作,一次只能有一个线程加写锁。在进行写操作时,不能加读锁。见源文件:lock/ReadWriteLockTest.java,基于线程锁的缓存机制,缓存是内存中的一块特殊区域,用于存放应用系统中经常会用到的数据,用以减少数据库的查询操作以提高应用系统性能。缓存机制普遍存在于计算机应用中,例如Hibernate框架的Session,存在两级缓存机制。见源文件:缓存/CacheTest.java,利用Condition实现线程间通信,线程间通信都是基于生产生和消费者模型的。传统的线程间通信方式:在线程同步的基础上,不同的线程对同一个对象加锁并执行wait()和nofify()方法。见源文件:condition/TraditionTest.javaCondition的功能类似于传统Object.wait()和Object.notify()方法,Condition对象由Lock对象的newCondition()对象创建。通过执行signal()和await()方法在线程间通信。见源文件:condition/ConditionTest.javaCondition对象的一个优势在于能够方便实现多个线程间(线程个数大于2个)的通信。见源文件:condition/ThreeConditionTest.java,利用Semaphore控制线程并发个数,Semaphore在提供线程同步的基础上,用来控制线程并发的个数。(1)例如有5个座位,10个人要来坐,一次同时能容纳5个人坐,只能等到有人离开后,其余人才能坐。坐这个座位要获得许可权,这个许可权就是Semaphore。(2)剩余的5个人随机获得许可权,或者按照Semaphore设定的顺序来获得许可权。见源文件:Semaphore/SemaphoreTest.java,CyclicBarrier同步工具,一个同步辅助类,它允许一组线程互相等待,直到到达某个公共屏障点(commonbarrierpoint)。公共屏障点可以在线程运行过程中设置多次。,例如:大家约好7点在学校门口集合(屏障),然后一起出发去公园,到公园后自由活动,下午5点在公园门口集合(屏障)返回。见源文件:CyclicBarrier/CyclicBarrierTest.java,CountDownLatch同步工具,倒计时计数器,调用该对象的countDown()方法将技术值减1,等到减到0为止,所有等待该计数器的线程开始运行。应用场景:在比赛中,所有运动员等到裁判鸣哨,然后比赛开始,裁判等到所有运动员到终点后,比赛结束。见源文件:CountDownLatch/CountDownLatchTest.java,CountDownLatch同步工具,模拟抢红包程序中存在一个缺陷:最先启动的线程抢到红包的概率是很大的,那么如何该让所有的线程都具备抢到红包的概率呢?解决思路:让所有线程都启动后等待一个计数器,当这个计数器减为0时,再这些线程来执行抢红包的逻辑,这样的话所有线程的机会都是相等的。见源文件:CountDownLatch/BonusTest1.java,Exchanger数据交换工具,Exchanger用于在两个线程之间交换数据,其中一个线程执行一定的逻辑后需要把自己的某个数据和另一个线程的数据进行交换,这个线程就要等待另一个线程的到来,两者交换数据后再独自运行。应用场景:两个人相约某个时刻到某个地点进行交易,两个人都到了之后,一手交钱,一手交货,然后各忙各的了。见源文件:Exchanger/ExchangerTest.java,阻塞队列,阻塞队列常用于多线程编程中,由于协调线程之间的合作;当队列是空的时,从队列中获取元素的操作将会被阻塞,或者当队列是满时,往队列里添加元素的操作会被阻塞。BlockingQueue是个接口,有如下实现类:1.ArrayBlockQueue:一个由数组支持的有界阻塞队列。此队列按FIFO(先进先出)原则对元素进行排序。2.LinkedBlockQueue:一个可改变大小的阻塞队列。此队列按FIFO(先进先出)原则对元素进行排序。创建其对象如果没有明确大小,默认值是Integer.MAX_VALUE。3.PriorityBlockingQueue:类似于LinkedBlockingQueue,但其所含对象的排序不是FIFO,而是依据对象的自然排序顺序或者是构造函数所带的Comparator决定的顺序。4.SynchronousQueue:同步队列。同步队列没有任何容量,每个插入必须等待另一个线程移除,反之亦然。见源文件:BlockingQueue/BlockingQueueTest.java,阻塞队列,应用场景:可以利用两个只包含一个元素的阻塞队列实现线程同步(生产者-消费者)。见源文件:BlockingQueue/BlockingQueueTest1.java,Queue1.put(),Queue2.take(),Queue2.put(),Queue1.take(),Queue1.put(),Queue2.put(),相关练习,(1)已知有16个日志对象,在一个线程中每隔1秒打印一条日志对象,程序源码如备注所示。要求:在源代码基础上进行修改,要求采用4个线程在4秒中将日志对象打印完毕。见源文件:BlockingQueue/BlockingQueueT
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 执法演讲面试题目及答案
- 先进制造市场分析与经营
- 环境评价公众参与机制在2025年公众参与评价与环境保护教育中的应用报告
- 供电试岗期满考试试题及答案
- 2025年运动控制 试题及答案
- 益智课程考试题及答案
- 2025年食堂食品安全管理人员考试试题及答案
- 2025年flash动画制作考试题及答案
- 2025年法语考试题目及答案
- 2025年陕西省辅警协警笔试笔试真题含答案
- 道路运输安全员考试题库及答案
- 2025重庆某国有企业招聘新媒体运营(偏拍摄剪辑)参考题库含答案
- 2025年秋期新教材部编人教版一年级上册道德与法治教学计划+进度表
- 医院绩效考核指标体系设计与实施
- 2025年农业农村局公务员招聘面试指南与模拟题解析
- 食堂食品安全风险日管控、周排查、月调度管理制度
- 2025年秋季新学期全体教职工大会上校长讲话:汇一股心力、立两个目标、守三条底线、打四场硬仗
- 2025至2030中国水射流强化泵行业项目调研及市场前景预测评估报告
- 2025年北师大版新教材数学三年级上册教学计划(含进度表)
- 招投标技术服务及售后承诺书
- 《推销实务》中职全套教学课件
评论
0/150
提交评论