




已阅读5页,还剩2页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
目录1.理解多线程12.创建线程13. Callable接口和Future接口34.线程池5通过本次项目开发,我接触到了多线程的知识,在项目结束之际,我将我对多线程的了解总结了出来,供大家参考。1.理解多线程多线程是这样一种机制,它允许在程序中并发执行多个指令流,每个指令流都称为一个线程,彼此间互相独立。线程又称为轻量级进程,它和进程一样拥有独立的执行控制,由操作系统负责调度,区别在于线程没有独立的存储空间,而是和所属进程中的其它线程共享一个存储空间,这使得线程间的通信远较进程简单。多个线程的执行是并发的,也就是在逻辑上“同时”,而不管是否是物理上的“同时”。如果系统只有一个CPU,那么真正的“同时”是不可能的,但是由于CPU的速度非常快,用户感觉不到其中的区别,因此我们也不用关心它,只需要设想各个线程是同时执行即可。多线程和传统的单线程在程序设计上最大的区别在于,由于各个线程的控制流彼此独立,使得各个线程之间的代码是乱序执行的,由此带来的线程调度,同步等问题,将在以后探讨。2.创建线程线程的实现有2种方法,一是继承Thread类来创建线程,二是使用Runnable接口来创建线程。Java1.5中增强了对于采用Runnable接口实现线程类的控制方法类,增加了Callable接口和Future接口来获得线程执行的结果和控制执行状况。另外,线程的获得上,不一定都要重新创建新线程,可预先创建一个线程池,以后需要使用线程的时候直接从线程池中获得;多个相似线程也可以组织到线程组中。继承Thread类创建线程继承 Thread 类,覆盖方法 run(),我们在创建的 Thread 类的子类中重写 run() ,加入线程所要执行的代码即可。下面是一个例子:public class MyThread extends Threadint number;public MyThread(int num)number = num;System.out.println(创建线程 + number);public void run() System.out.println(线程 + number + 完成 );public static void main(String args)for(int i = 0;i5; i+) new MyThread(i+1).start();运行结果:创建线程 1创建线程 2创建线程 3创建线程 4线程 1完成线程 2完成创建线程 5线程 3完成线程 4完成线程 5完成这个方法有个很大的缺点就是,如果我们的类已经从一个类继承,则无法再继承 Thread 类,这时如果我们又不想建立一个新的类,应该怎么办呢?我们不妨来探索一种新的方法:我们不创建Thread类的子类,而是直接使用它,那么我们只能将我们的方法作为参数传递给 Thread 类的实例,有点类似回调函数。但是 Java 没有指针,我们只能传递一个包含这个方法的类的实例。那么如何限制这个类必须包含这一方法呢?当然是使用接口!Java 提供了接口 java.lang.Runnable 来支持这种方法。实现Runnable接口创建线程Runnable接口只有一个方法run(),我们声明自己的类实现Runnable接口并提供这一方法,将我们的线程代码写入其中,就完成了这一部分的任务。但是Runnable接口并没有任何对线程的支持,我们还必须创建Thread类的实例,这一点通过Thread类的构造函数 public Thread(Runnable target)来实现。下面是一个例子:public class MyThread implements Runnableint number;public MyThread(int num)number = num;System.out.println(创建线程 + number);public void run() System.out.println(线程 + number + 完成);public static void main(String args)for(int i = 0;i5; i+) new Thread(new MyThread(i+1).start();运行结果:创建线程 1创建线程 2创建线程 3线程 1完成线程 2完成创建线程 4创建线程 5线程 3完成线程 4完成线程 5完成 红色字体部分是以上两段代码的不同之处,可以看到,无论哪种方法创建多线程,都要实现public void run()方法,并且启动线程用start方法。两种实现方式的比较虽然使用继承Thread的方式实现简单,但很少使用,通常我们都是通过实现Runnable接口来实现线程,其好处主要有两点:1、结构清晰:把CPU和代码段以及数据段分离,如果采用继承的方式,则三者混在一起,逻辑凌乱,代码和数据的共享也很困难。2、避免Java单继承体系的限制。如果一个子类想通过线程调度,则只能采用实现Runnable接口,因为Java不允许一个子类有多个父类。3. Callable接口和Future接口 实现Runnable接口的类内封装了异步运行的任务,任务封装在run方法内,但是该方法没有参数没有返回值;而且对于任务的控制难以实现(比如任务是否完成,取消任务等)。Callable接口Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。Callable和Runnable有几点不同:1、 Callable规定的方法是call(),而Runnable规定的方法是run(). 2、 Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。 3、 call()方法可抛出异常,而run()方法是不能抛出异常的。 4、 运行Callable任务可拿到一个Future对象,通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。5、 Callable接口对象不能直接作为线程的构造目标,只有Runnable接口对象可以。6、 Callable是一个泛型,并且它的结果已经参数化。Callable接口的定义原型为:public interface CallableV call() throws Exception; Future接口Future接口用来保存异步计算的处理结果,并且可以控制异步计算。我们要做的就是生成Future对象,然后把该对象交给一个线程,线程启动计算过程,计算的结果保存为Future对象,同时还可以通过Future对象来控制计算过程。Future的接口的定义原型为:public interface FutureV get() throws . . .;/阻塞取得异步计算结果,直到计算取得结果为止V get(long timeout, TimeUnit unit) throws . . .; /阻塞取得异步计算结果,直到计算完成所给定的时间之后void cancel(boolean mayInterrupt);/取消运算boolean isCancelled();/判断计算是否已取消boolean isDone();/判断运算是否已经完成那么怎么Java提供了FutureTask类,该类实现了Future和Runnable接口,并且Future接口和Runnable接口的方法都有默认实现(不需要用户实现),因此FutureTask可以很方便的把Callable转换成Future和Runnable:Callable myComputation = . . .;FutureTask task = new FutureTask(myComputation);Thread t = new Thread(task); / its a Runnablet.start();. . .Integer result = task.get(); / its a Future我们来看一个例子:import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;public class MyThread implements Callable private int number;public MyThread(int num) number = num;System.out.println(创建线程 + number);public String call() return 线程 + number + 完成 ;public static void main(String args) Callable myCallable = null;FutureTask task = null;for (int i = 0; i 5; i+) myCallable = new MyThread(i+1);task = new FutureTask(myCallable);new Thread(task).start(); / its a Runnabletry System.out.println(task.get();/ its a Future catch (InterruptedException e) e.printStackTrace(); catch (ExecutionException e) e.printStackTrace();运行结果:创建线程1线程 1完成创建线程2线程 2完成创建线程3线程 3完成创建线程4线程 4完成创建线程5线程 5完成4.线程池线程池(thread pool)是预创建好的线程和集合,当我们需要使用线程对象的时候,不需要每次都重新创建线程,只需要从线程池中取出一个空闲线程,然后把Runnable对象交给该线程运行即可;当线程运行完毕,该线程也不会真的消亡,只是“还”给线程池。为什么要使用线程池,有两个理由:1. 减少创建线程的开销每个线程的创建多需要有代价的,如果我们的应用中有大量的生命周期很短的线程,则对系统性能影响较大。如果从线程池中获得和释放线程,性能提高明显。2. 控制线程的数量系统的总的负载能力是有一定限制的(因为系统资源限制),通过线程池我们可以限制最大的线程数量来防止系统负载过高。Executors类Java提供了Executors类来创建线程池,此类支持以下各种方法: 1、 创建并返回设置有常用配置字符串的 ExecutorService 的方法。 2、 创建并返回设置有常用配置字符串的 ScheduledExecutorService 的方法。 3、 创建并返回“包装的”ExecutorService 方法,它通过使特定于实现的方法不可访问来禁用重新配置。 4、 创建并返回 ThreadFactory 的方法,它可将新创建的线程设置为已知的状态。 5、 创建并返回非闭包形式的 Callable 的方法,这样可将其用于需要 Callable 的执行方法中。Executors中提供了一些方法可以很方便的创建线程池:newCachedThreadPool()创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行很多短期异步任务的程序而言,这些线程池通常可提高程序性能。newFixedThreadPool(int nThreads)创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。newSingleThreadExecutor()创建一个使用单个 worker 线程的 Executor,以无界队列方式来运行该线程。在使用Executors时,先调用这些静态方法创建线程池,得到一个ExecutorService对象,然后用这个对象的submit方法提交你的Runnable或是Callable对象。Future submit(Runnable task)提交一个 Runnable 任务用于执行,并返回一个表示该任务的 Future。Future submit(Runnable task, T result)提交一个 Runnable 任务用于执行,并返回一个 Future,该 Future 表示任务一旦完成后即返回给定的结果。Future submit(Callable task)提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。如果不再需要任何提交,就用shutdown方法来关闭线程池。例如,当我们想要异步执行一个Callable任务,我们将它传递给ExecutorService的submit()方法。submit()的返回值是一个Future对象:本质上是一个对将来某时刻的结果的“借条”。如果我们准备使用我们的任务的结果,我们简单的调用Future对象的get()方法即可。如果任务的执行已完成,那么get()立刻返回结果。否则,它将阻塞直到结果可用。如果Callable抛出异常,那么get()方法将该异常包装为ExecutionException并且抛出它。Future还有方法用来对任务的执行进行取消和查询状态。Future也用了泛型,并且结果的类型也参数化了。例子代码如下:import java.util.ArrayList;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;public class MyThread implements Callable
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026华能山东石岛湾核电有限公司应届高校毕业生招聘笔试参考题库附答案解析
- 江西司法警官职业学院2025年公开招聘第二批编外合同制教师【72人】笔试参考题库附答案解析
- 2025年【黑龙江人才周】齐齐哈尔市重点企业招聘754人笔试参考题库附答案解析
- 2025年河北廊坊市安次区码头镇西安庄小学招聘合同制教师1名笔试参考题库附答案解析
- 景德镇市人民检察院2025年度公开招聘聘用制书记员【6人】笔试模拟试题及答案解析
- 2025广东广州市海珠区海幢街道招聘公益性岗位1人笔试备考题库及答案解析
- 2025年蚌埠高新区天河社区行政事务管理中心公开招聘编外工作人员笔试备考试题及答案解析
- 2025福建福州市水务文化旅游有限公司招聘3人笔试备考题库及答案解析
- 银行自动柜员机操作流程
- 节粮减粮主题班会活动方案
- 船员技能评估体系-洞察及研究
- 中职手工课课件
- 2025至2030中国军用降落伞行业运营态势与投资前景调查研究报告
- 孕妇孕期心理健康管理策略
- 血尿临床评估与健康管理
- 毕业设计(论文)-芦苇草方格铺设装置设计
- 教育惩戒培训课件
- 期末教学质量分析会校长讲话:把脉找因、沉心补课教学质量没有“回头路”
- 调经补血中药液行业跨境出海项目商业计划书
- 手术后疼痛评估与护理团体标准
- 五金公司质量管理制度
评论
0/150
提交评论