java多线程的几种实现方式

1.继承Thread类,重写run方法
2.实现Runnable接口,重写run方法,实现Runnable接口的实现类的实例对象作为Thread构造函数的target
3.通过Callable和FutureTask创建线程
4.通过线程池创建线程  (上一篇已经讲过了)

前面两种可以归结为一类:无返回值,原因很简单,通过重写run方法,run方式的返回值是void,所以没有办法返回结果 
后面两种可以归结成一类:有返回值,通过Callable接口,就要实现call方法,这个方法的返回值是Object,所以返回的结果可以放在Object对象中

继承Thread类的线程

实现方式如下:

public class ThreadDemo01 extends Thread{
public ThreadDemo01(){
//编写子类的构造方法,可缺省
}
public void run(){
//编写自己的线程代码
System.out.println(Thread.currentThread().getName());
}
public static void main(String[] args){
ThreadDemo01 threadDemo01 = new ThreadDemo01();
threadDemo01.setName("我是自定义的线程1");
threadDemo01.start();
System.out.println(Thread.currentThread().toString());
}
}

程序结果: 
Thread[main,5,main] 
我是自定义的线程1

实现Runnable接口,实现run方法

接口的实现类的实例作为Thread的target作为参数传入带参的Thread构造函数,通过调用start()方法启动线程

public class ThreadDemo02 {

    public static void main(String[] args){
System.out.println(Thread.currentThread().getName());
Thread t1 = new Thread(new MyThread());
t1.start();
}
} class MyThread implements Runnable{
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+"-->我是通过实现接口的线程实现方式!");
}
}

程序运行结果: 
main 
Thread-0–>我是通过实现接口的线程实现方式!

通过Callable和FutureTask创建线程

a:创建Callable接口的实现类 ,并实现Call方法 
b:创建Callable实现类的实现,使用FutureTask类包装Callable对象,该FutureTask对象封装了Callable对象的Call方法的返回值 
c:使用FutureTask对象作为Thread对象的target创建并启动线程 
d:调用FutureTask对象的get()来获取子线程执行结束的返回值

public class ThreadDemo03 {

    /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub Callable<Object> oneCallable = new Tickets<Object>();
FutureTask<Object> oneTask = new FutureTask<Object>(oneCallable); Thread t = new Thread(oneTask); System.out.println(Thread.currentThread().getName()); t.start(); } } class Tickets<Object> implements Callable<Object>{ //重写call方法
@Override
public Object call() throws Exception {
// TODO Auto-generated method stub
System.out.println(Thread.currentThread().getName()+"-->我是通过实现Callable接口通过FutureTask包装器来实现的线程");
return null;
}
}

程序运行结果: 
main 
Thread-0–>我是通过实现Callable接口通过FutureTask包装器来实现的线程

通过线程池创建线程

public class ThreadDemo05{

    private static int POOL_NUM = 10;     //线程池数量

    /**
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
ExecutorService executorService = Executors.newFixedThreadPool(5);
for(int i = 0; i<POOL_NUM; i++)
{
RunnableThread thread = new RunnableThread(); //Thread.sleep(1000);
executorService.execute(thread);
}
//关闭线程池
executorService.shutdown();
} } class RunnableThread implements Runnable
{
@Override
public void run()
{
System.out.println("通过线程池方式创建的线程:" + Thread.currentThread().getName() + " "); }
}

程序运行结果:

通过线程池方式创建的线程:pool-1-thread-3
通过线程池方式创建的线程:pool-1-thread-4
通过线程池方式创建的线程:pool-1-thread-1
通过线程池方式创建的线程:pool-1-thread-5
通过线程池方式创建的线程:pool-1-thread-2
通过线程池方式创建的线程:pool-1-thread-5
通过线程池方式创建的线程:pool-1-thread-1
通过线程池方式创建的线程:pool-1-thread-4
通过线程池方式创建的线程:pool-1-thread-3
通过线程池方式创建的线程:pool-1-thread-2

ExecutorService、Callable都是属于Executor框架。返回结果的线程是在JDK1.5中引入的新特征,还有Future接口也是属于这个框架,有了这种特征得到返回值就很方便了。 
通过分析可以知道,他同样也是实现了Callable接口,实现了Call方法,所以有返回值。这也就是正好符合了前面所说的两种分类

执行Callable任务后,可以获取一个Future的对象,在该对象上调用get就可以获取到Callable任务返回的Object了。get方法是阻塞的,即:线程无返回结果,get方法会一直等待。

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

总结:
引用阿里的关于  线程的建议:

原文链接:https://blog.csdn.net/java_zyq/article/details/87917734

java多线程的几种实现方式的更多相关文章

  1. Java多线程的三种实现方式

    java多线程的三种实现方式 一.继承Thread类 二.实现Runnable接口 三.使用ExecutorService, Callable, Future 无论是通过继承Thread类还是实现Ru ...

  2. 阿里巴巴--java多线程的两种实现方式,以及二者的区别

    阿里巴巴面试的时候,昨天问了我java面试的时候实现java多线程的两种方式,以及二者的区别当时只回答了实现线程的两种方式,但是没有回答上二者的区别: java实现多线程有两种方式: 1.继承Thre ...

  3. Java多线程的两种实现方式

    Java总共有两种方式实现多线程 方式1:通过继承Thread类的方式 package com.day04; /** * 通过继承Thread类并复写run方法来是实现多线程 * * @author ...

  4. java多线程的几种实现方式记录

    传统的实现线程的方式为三种,分别为继承Thread类,重写run()方法:实现Runable接口,重写run()方法:实现callable接口,重写call()方法:下面来记录一下最基本的三种编码实现 ...

  5. java 多线程编程三种实现方式

    一种是继承Thread类,一种是实现Runable接口,还有一种是实现callable接口: 有博主说只有前面2种方式,我个人愚见是三种,主要详细介绍下callable的使用: 三种线程的我的个人理解 ...

  6. java多线程的四种实现方式

    主要有四种:继承Thread类.实现Runnable接口.实现Callable接口通过FutureTask包装器来创建Thread线程.使用ExecutorService.Callable.Futur ...

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

    方式一:继承Thread类 1.创建一个继承于Thread类的子类 2.重写Thread类的run()方法---> 将此线程执行的操作声明在run()中 3.创建Thread类的子类的对象 4. ...

  8. Java多线程的几种创建方式

    方法一:继承Thread类,重写run方法,直接调用start方法开启线程. /** * 继承Thread类,直接调用start方法开启线程. * @author LuRenJia */ public ...

  9. 创建Java多线程的两种方式和线程异常

    一.使用多线程的两种方法  使用多线程的两种方法有:继承Thread类和实现runable接口. 二.继承Thread类 来看一下thread类的源代码: class Thread implement ...

随机推荐

  1. zookeeper shell

    1.启动zk客户端 ./zkCli.sh -server 192.168.67.35:2182,192.168.67.36:2182,192.168.67.37:2182   2.创建zk节点 cre ...

  2. 2018-2019-2 网络对抗技术 20165318 Exp 9 Web安全基础

    2018-2019-2 网络对抗技术 20165318 Exp 9 Web安全基础 基础问题回答 实践过程记录 WebGoat安装 SQL注入攻击 1.命令注入(Command Injection) ...

  3. 【操作系统之四】Linux常用命令之awk

    一.概念awk是一个报告生成器,拥有强大的文本格式化能力. 数据可以来自标准输入(stdin).一个或多个文件,或其它命令的输出: 依次对每一行进行处理,然后输出: 它在命令行中使用,但更多是作为脚本 ...

  4. jvm jdk jre 关系

    JDK : Java Development ToolKit(Java开发工具包).JDK是整个JAVA的核心,包括了Java运行环境(Java Runtime Envirnment),一堆Java工 ...

  5. JVM常用命令和性能调优建议 [Could not create the Java virtual machine]

    一.查看jvm常用命令jinfo:可以输出并修改运行时的java 进程的opts. jps:与unix上的ps类似,用来显示本地的java进程,可以查看本地运行着几个java程序,并显示他们的进程号. ...

  6. docker compose 编排

    Compose是Docker的服务编排工具,主要用来构建基于Docker的复杂应用,Compose 通过一个配置文件来管理多个Docker容器,非常适合组合使用多个容器进行开发的场景. 说明:Comp ...

  7. [转帖]自动交互式脚本--expect

    自动交互式脚本--expect https://www.cnblogs.com/zhuiluoyu/p/4873869.html 我们经常会遇到一些需要与服务器程序打交道的场景,比如,从登陆某个服务器 ...

  8. docker搭建etcd集群环境

    其实关于集群网上说的方案已经很多了,尤其是官网,只是这里我个人只有一个虚拟机,在开发环境下建议用docker-compose来搭建etcd集群. 1.拉取etcd镜像 docker pull quay ...

  9. mysql提示The server quit without updating PID file /usr/local/mysql/data/localhost.localdomain.pid

    chown -R mysql:mysql /var/lib/mysql 解决方法 :给予权限,执行 “chown -R mysql:mysql /var/lib/mysql” “chmod -R 75 ...

  10. TServerSocket组件

    主要作为服务器端的套接字管理器使用.它封装了服务器端的套接字.在打开套接字后,服务器端就处于监听状态,在接收到其它机器的连接请求后,与客户端建立连接,创建一个新的套接字,用于和客户端互传数据,此时TS ...