java实现线程的3中方式
1、继承Thread类实现多线程
继承Thread类的方法尽管被我列为一种多线程实现方式,但Thread本质上也是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。例如:
- public class MyThread extends Thread {
 - public void run() {
 - System.out.println("MyThread.run()");
 - }
 - }
 
在合适的地方启动线程如下:
- MyThread myThread1 = new MyThread();
 - MyThread myThread2 = new MyThread();
 - myThread1.start();
 - myThread2.start();
 
2、实现Runnable接口方式实现多线程
如果自己的类已经extends另一个类,就无法直接extends Thread,此时,必须实现一个Runnable接口,如下:
- public class MyThread extends OtherClass implements Runnable {
 - public void run() {
 - System.out.println("MyThread.run()");
 - }
 - }
 
为了启动MyThread,需要首先实例化一个Thread,并传入自己的MyThread实例:
- MyThread myThread = new MyThread();
 - Thread thread = new Thread(myThread);
 - thread.start();
 
事实上,当传入一个Runnable target参数给Thread后,Thread的run()方法就会调用target.run(),参考JDK源代码:
- public void run() {
 - if (target != null) {
 - target.run();
 - }
 - }
 
3、使用ExecutorService、Callable、Future实现有返回结果的多线程
ExecutorService、Callable、Future这个对象实际上都是属于Executor框架中的功能类。想要详细了解Executor框架的可以访问http://www.javaeye.com/topic/366591 ,这里面对该框架做了很详细的解释。返回结果的线程是在JDK1.5中引入的新特征,确实很实用,有了这种特征我就不需要再为了得到返回值而大费周折了,而且即便实现了也可能漏洞百出。
可返回值的任务必须实现Callable接口,类似的,无返回值的任务必须Runnable接口。执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了,再结合线程池接口ExecutorService就可以实现传说中有返回结果的多线程了。下面提供了一个完整的有返回结果的多线程测试例子,在JDK1.5下验证过没问题可以直接使用。代码如下:
- import java.util.concurrent.*;
 - import java.util.Date;
 - import java.util.List;
 - import java.util.ArrayList;
 - /**
 - * 有返回值的线程
 - */
 - @SuppressWarnings("unchecked")
 - public class Test {
 - public static void main(String[] args) throws ExecutionException,
 - InterruptedException {
 - System.out.println("----程序开始运行----");
 - Date date1 = new Date();
 - int taskSize = 5;
 - // 创建一个线程池
 - ExecutorService pool = Executors.newFixedThreadPool(taskSize);
 - // 创建多个有返回值的任务
 - List<Future> list = new ArrayList<Future>();
 - for (int i = 0; i < taskSize; i++) {
 - Callable c = new MyCallable(i + " ");
 - // 执行任务并获取Future对象
 - Future f = pool.submit(c);
 - // System.out.println(">>>" + f.get().toString());
 - list.add(f);
 - }
 - // 关闭线程池
 - pool.shutdown();
 - // 获取所有并发任务的运行结果
 - for (Future f : list) {
 - // 从Future对象上获取任务的返回值,并输出到控制台
 - System.out.println(">>>" + f.get().toString());
 - }
 - Date date2 = new Date();
 - System.out.println("----程序结束运行----,程序运行时间【"
 - + (date2.getTime() - date1.getTime()) + "毫秒】");
 - }
 - }
 - class MyCallable implements Callable<Object> {
 - private String taskNum;
 - MyCallable(String taskNum) {
 - this.taskNum = taskNum;
 - }
 - public Object call() throws Exception {
 - System.out.println(">>>" + taskNum + "任务启动");
 - Date dateTmp1 = new Date();
 - Thread.sleep(1000);
 - Date dateTmp2 = new Date();
 - long time = dateTmp2.getTime() - dateTmp1.getTime();
 - System.out.println(">>>" + taskNum + "任务终止");
 - return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";
 - }
 - }
 
代码说明:
上述代码中Executors类,提供了一系列工厂方法用于创先线程池,返回的线程池都实现了ExecutorService接口。
public static ExecutorService newFixedThreadPool(int nThreads)
创建固定数目线程的线程池。
public static ExecutorService newCachedThreadPool()
创建一个可缓存的线程池,调用execute 将重用以前构造的线程(如果线程可用)。如果现有线程没有可用的,则创建一个新线程并添加到池中。终止并从缓存中移除那些已有 60 秒钟未被使用的线程。
public static ExecutorService newSingleThreadExecutor()
创建一个单线程化的Executor。
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize)
创建一个支持定时及周期性的任务执行的线程池,多数情况下可用来替代Timer类。 ExecutoreService提供了submit()方法,传递一个Callable,或Runnable,返回Future。如果Executor后台线程池还没有完成Callable的计算,这调用返回Future对象的get()方法,会阻塞直到计算完成。
}
java实现线程的3中方式的更多相关文章
- 操作系统实现线程的几种模式 和 java创建线程的3个方式
		
操作系统实现线程的几种模式 和 java创建线程的3个方式 这是两个概念 在操作系统中,线程可以实现在用户模式下,也可以实现在内核模式下,也可以两者结合实现. 1.实现线程的三种方式: (1)继承t ...
 - Java创建线程的四种方式
		
Java创建线程的四种方式 1.继承Thread类创建线程 定义Thread类的子类,并重写该类的run方法,run()方法的内容就是该线程执行的内容 创建Thread子类的实例,即创建了线程对象. ...
 - 当阿里面试官问我:Java创建线程有几种方式?我就知道问题没那么简单
		
这是最新的大厂面试系列,还原真实场景,提炼出知识点分享给大家. 点赞再看,养成习惯~ 微信搜索[武哥聊编程],关注这个 Java 菜鸟. 昨天有个小伙伴去阿里面试实习生岗位,面试官问他了一个老生常谈的 ...
 - Java新建线程的两种方式
		
Java新建线程有两种方式,一种是通过继承Thread类,一种是实现Runnable接口,下面是新建线程的两种方式. 我们假设有个竞赛,有一个选手A做俯卧撑,一个选手B做仰卧起坐.分别为两个线程: p ...
 - Java实现线程的三种方式和区别
		
Java实现线程的三种方式和区别 Java实现线程的三种方式: 继承Thread 实现Runnable接口 实现Callable接口 区别: 第一种方式继承Thread就不能继承其他类了,后面两种可以 ...
 - Java并发编程:Java创建线程的三种方式
		
目录 引言 创建线程的三种方式 一.继承Thread类 二.实现Runnable接口 三.使用Callable和Future创建线程 三种方式的对比 引言 在日常开发工作中,多线程开发可以说是必备技能 ...
 - java创建线程的三种方式及其对比
		
第一种方法:继承Thread类,重写run()方法,run()方法代表线程要执行的任务.第二种方法:实现Runnable接口,重写run()方法,run()方法代表线程要执行的任务.第三种方法:实现c ...
 - AJPFX总结java创建线程的三种方式及其对比
		
Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行 ...
 - java创建线程的三种方式及其对照
		
Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)定义Thread类的子类.并重写该类的run方法,该run方法的方法体就代表了线程要完毕的任务.因此把run()方法称为运行 ...
 
随机推荐
- jmeter对http协议中post请求接口测试
			
现在有很多的工具用于工作上的使用,在jmeter的开源工具当中的,提供了一个可以对http协议的post的请求上接口测试,用于实现接口测试的自动化测试,当然也可以使用自己写的工具. 进行打开jmet ...
 - javabean解决jsp中中文乱码问题
			
问题描述:useBean行为定义了Java Bean对象(Person类包括姓名[string],年龄[int]),使用html页面向JSP页面提交数据,JSP页面中使用Java Bean行为来处理提 ...
 - windows上安装ubuntukylin16.04并且在ubuntukylin上安装jdk
			
1.安装ubuntukylin16.04 教程链接:http://jingyan.baidu.com/article/f71d60379824041ab641d19d.html 我是完全按照这个教程来 ...
 - HTML中判断手机是否安装某APP,跳转或下载该应用
			
有些时候在做前端输出的时候,需要和app的做些对接工作.就是在手机浏览器中下载某app时,能判断该用户是否安装了该应用.如果安装了该应用,就直接打开该应用:如果没有安装该应用,就下载该应用.那么下面就 ...
 - Python语法基础(长期)
			
os.mkdir和os.mkdirs的区别? 前者如果"中间路径"不存在,会抛出异常,后者则会自动创建中间路径. map(function, iterable) 对于可迭代函数`` ...
 - Python基础(五)-函数
			
函数: 1.定义与使用: def 函数名(参数): "函数_文档字符串" 函数体 ... return [表达式] ## def:表示函数的关键字 函数名:函数名称,根据函数名调用 ...
 - 主机连不上虚拟机中的Redis的原因分析、以及虚拟机网络配置
			
1. 网络最好是桥接方式.我之前用的是"网络地址转换(NAT)",导致虚拟机里用命令ifconfig得到的ip是10.0.2.15,好奇怪的感觉,然后在真实机上一直连不上.有的说用 ...
 - jquery复选框操作
			
$('input[type="checkbox"]').change(function(e) { var checked = $(this).prop("checked& ...
 - Objective-C与Swift下的自定义打印函数(Debug和Release)
			
1.Objective-C 在使用Objective-C进行开发的过程中,为了Debug会不断的设置打印函数.如下图是我们经常用的,用来测试监听方法的实现与否: NSLog(@"%s&quo ...
 - 路由页面缓存开启 以及 keep-alive 给你埋下的坑
			
为什么要用keep-alive呢, 因为这个会缓存dom模板, 下次再回到这个页面, 就可以利用这个已经渲染好的dom结构了, 如果数据不一样, 也会启用 virtualDoM 进行diff更新, 这 ...