Java多线程实现方式主要有三种:继承Thread类、实现Runnable接口、使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,只有最后一种是带返回值的。

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()方法,会阻塞直到计算完成。

转载于:http://www.cnblogs.com/yezhenhan/archive/2012/01/09/2317636.html

转载于:https://www.cnblogs.com/rinack/p/7779315.html

Java创建多线程的三种方法相关推荐

  1. Java 创建线程的三种方法比较

    在学习编程的过程中,我觉得不止要获得课本的知识,更多的是通过学习技术知识提高解决问题的能力,这样我们才能走在最前方,本文主要讲述Java 创建线程的三种方法比较, 更多Java专业知识,广州疯狂jav ...

  2. Python创建多线程的三种方法

    Python创建多线程的三种方法 thread模块函数式创建线程 继承threading类创建多线程 threading模块函数式创建线程 使用总结 thread模块函数式创建线程 调用thread模 ...

  3. Java创建线程的三种方法

    这里不会贴代码,只是将创建线程的三种方法做个笼统的介绍,再根据源码添加上自己的分析. 通过三种方法可以创建java线程: 1.继承Thread类. 2.实现Runnable接口. 3.实现Callab ...

  4. Java创建数组的三种方法

    ■ 第一种: int[] arr=new int[6]; arr[0] = 1; arr[1] = 2 arr[2] = 3; arr[3] = 4; arr[4] = 5; arr[5] = 6; ...

  5. java 创建线程的三种方法_java 创建线程的几种方式

    说道线程,肯定会想到使用 java.lang.Thread.java这个类 那么创建线程也主要有2种方式 第一种方式: public class MyThread extends Thread { p ...

  6. java创建restful接口,三种方法实现java调用Restful接口

    转自:https://www.cnblogs.com/taozhiye/p/6704659.html 引言:当前,web开发中第三方接口的选择往往是在restful接口和web service 接口 ...

  7. java多线程w3c_Java创建多线程的三种方式

    前言 这篇文章主要讲述线程的概念.组成.Java创建多线程的三种方式以及线程的类型. 线程概念 线程和进程的区别 **进程:**正在运行的程序,例如:你打开 的qq音乐.exe程序,其由PCB(进程控 ...

  8. Java创建数组的三种方式 (以及length方法是否能获取数组中元素的个数)

    Java创建数组的三种方法 import java.util.Arrays; public class Sum { public static void main(String[] args){ in ...

  9. Java创建数组的三种方法和ArrayList的用法

    Java创建数组的三种方法和ArrayList的用法 Java创建数组的三种方法 一.声明并赋值 二.声明数组名开辟空间 三.声明数组并指定元素个数 四.多维数组 ArrayList的用法 一.添加元 ...

最新文章

  1. opencv mat用数组初始化_10、OpenCV中图像和Mat类型(一)
  2. 末日来临,你的编程语言能干嘛? | 每日趣闻
  3. JavaScript中的JSON
  4. Java黑皮书课后题第2章:2.1(将摄氏温度转换为华氏温度)编写程序,从控制台读入double型的摄氏温度值,将其转为华氏温度,显示结果
  5. SAP 电商云 Spartacus UI 回归测试 checkout-flow.core-e2e-spec.ts
  6. scara机器人本体介绍
  7. php提交表单并发送邮件,php提交表单发送邮件的方法
  8. [转]bss,data,rodata,text
  9. 使用过滤器实现网站访问计数器的功能
  10. JS传值中文乱码解决方案
  11. 一个故事理解什么是接口回调
  12. AndroidLinux gdb用法
  13. 【Python实例第21讲】确定类个数的silhouette分析法
  14. Qwtpolar的编译
  15. arm64Linux网易云,网易云音乐arm版
  16. 2D虚拟试衣——服装变形
  17. cisp-pte考试经验分享
  18. 美团2021届秋季校园招聘笔试真题解析:小美的跑腿代购
  19. 基于 Ng-zorro-antd 的企业后台模板 ng-alain
  20. 日常英语口语收集汇总

热门文章

  1. linux c/c++
  2. “Zhuang.Data”轻型数据库访问框架(二)框架的入口DbAccessor对象
  3. memcpy的使用方法总结
  4. 从源文件中读出最后10KB内容到目的文件中
  5. vue动态获取元素距离页面顶部的高度_VUE如何实时监听元素距离顶部高度
  6. Python倒排索引函数
  7. 【Python-ML】SKlearn库RANSAC拟合高鲁棒性回归模型
  8. 全文检索工具迅搜的安装和体验(可用于自建中文全文搜索引擎)
  9. 修改mysql字符编码出现Job failed to start解决办法
  10. Learn About Bundles and the Request Lifecycle——未完待续