第一种:  通过继承Thread类创建线程

第二种: 通过实现Runnable接口创建线程

这两种早已烂记于心,这里就不作过多的介绍, 主要介绍其源码

Thread类 implements Runnable

thread空线程的run方法 是判断target是否存在实,再执行target实例中的run方法

public void run(){
if(this.target != null){
this.target.run();
}
}

通过实现Runnable接口, 并且通过thread构造函数创建线程的方法

Runnable runnable = new Runnable(){...重写run方法};

Thread thread_one = new Thread(runnable);
Thread thread_two = new Thread(runnable);

如果创建多个线程, 实质是多个线程引用同一个target 实例

对比两种方式的区别:

  通过继承Thread类实现多线程的方式由于单继承的局限性, 不能再继承其他类, 只能完成各自的任务

  通过实现Runnable接口实现多线程的方式能更好的做到并发完成同一个任务, 因为访问的是同一个target, 实现了共享数据

总之,在大多数情况下,都偏向于通过实现Runnable接口创建多线程

第三种: 使用Callable接口 和 FutureTask类创建线程

由于Thread类和Runnbale接口中的run方法没有返回值, 所以这两种方式不能获取异步执行的结果

Callable接口

package java.util.concurrent;
@FunctionalInterface
public interface Callable<V>{
V call() throws Exception;
}

@FunctionalInterface 注解标注在接口上, 表示此接口为"函数式接口"

函数式接口:  只有一个抽象方法的接口

此注解只是方便编译器进行检查, 不加也不会影响. 如果加了注解但该接口不是函数式接口,编译器会报错

Callable接口是泛型接口 ,也是函数式接口

call()抽象方法还有一个Exception的异常声明, 容许方法内的异常直接抛出,并且可以不予捕获

Future接口, RunnableFuture接口,以及FutureTask实现类都是位于 java.util.concurrent包下

V get()  用于阻塞性得到异步执行的结果.  此方法是阻塞性的,异步未执行完会处于阻塞状态

Object outcome  用于保存call()方法的异步执行结果.  get()会获取

创建线程的具体步骤

class ReturnableTask implements Callable<Long>{
public long call() throws Exception{
//线程要执行的代码
}
} public static void main(String args[]) throws InterruptedException{
ReturnableTask task = new new ReturnableTask();
Futuretask<Long> FutureTask = new Futuretask<Long>(task);
Thread thread = new Thread(FutureTask,"returnableThread");
thread.start();
System.out.println(FutureTask.get()); //得到异步执行结果
}

下图为具体实现过程

两个线程处于并发状态, 默认异步执行

看起来两个线程是同时进行,实质上是不是, 单个进程在同一时间只能执行一个进程,由于分给线程的时间片非常短(线程切换毫秒级),所以以为是同时

并发执行的消息通信机制分为同步和异步,  这些就不做过多解释

总之,图上的两个线程不是同时运行

第四种: 通过线程池创建线程

通过Thread创建线程在执行完就被销毁了, 不可服用. 在高并发场景中, 频繁创建线程是非常消耗资源的, 通过线程池创建线程可以对已经创建好的线程进行复用

Executors 静态工厂类  用于创建不同的线程池 java.util.concurrent;

//创建一个包含三个线程的线程池
private static ExecutorService pool = Executors.newFixedThreadPool(3);

Executor接口

  void executo(Runnable command);    //执行Runnable类型

ExecutorService<T> extends Executor

  <T> Future<T> submit(Callable<T> task)   //提交callable类型以执行

  Future<?> submit(Runnable task)      //提交Runnable类型以执行

具体实现

main
Future future = pool.submit(new RuturnableTask());
Long result = (Long) future.get(); //得到异步执行的结果

execute() 与 submit() 执行线程方法的区别

execute()只能执行Runnable, 并且无返回值

submit() 既能执行Runnable又能执行callable, 并且有返回值

注: 实际生产环境中禁止使用Executors创建线程池

java创建线程的四种方法的更多相关文章

  1. Java创建线程的四种方式

    Java创建线程的四种方式 1.继承Thread类创建线程 定义Thread类的子类,并重写该类的run方法,run()方法的内容就是该线程执行的内容 创建Thread子类的实例,即创建了线程对象. ...

  2. java创建线程的三种方法

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

  3. Java多线程——之一创建线程的四种方法

    1.实现Runnable接口,重载run(),无返回值 package thread; public class ThreadRunnable implements Runnable { public ...

  4. Java 创建线程的两种方法

    Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...

  5. Java创建线程的两种方法

    大多数情况,通过实例化一个Thread对象来创建一个线程.Java定义了两种方式: 实现Runnable 接口: 可以继承Thread类. 下面的两小节依次介绍了每一种方式. 实现Runnable接口 ...

  6. Java 创建线程的3种方法及各自优势

    1. 继承 Thread 类,然后调用 start 方法. class MyThread extends Thread { //重写run方法,线程运行后,跑的就是run方法 public void ...

  7. java 创建线程的三种方法Callable,Runnable,Thread比较及用法

    转自:http://www.chinaitlab.com/Java/line/942440.html 编写多线程程序是为了实现多任务的并发执行,从而能够更好地与用户交互.一般有三种方法,Thread, ...

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

    一般有三种方法,Thread,Runnable,Callable. Runnable和Callable的区别 (1)Callable规定的方法是call(),Runnable规定的方法是run(). ...

  9. 区分JAVA创建线程的几种方法

    1. start()和run()       通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行.然后 通过此Thread类调用方法run()来完成其运行操 ...

随机推荐

  1. ansible roles实践——服务器初始化

    1.服务器初始化可以做哪些工作 关闭selinux ntp同步时间 修改dns为自建dns 配置ssh互信 修改yum源 设置主机名 内核参数优化 安装jdk 2.roles编写

  2. nginx 和uwsgi的区别与作用

    在介绍nginx和uwsgi的区别和作用之前我们先介绍一下几个概念 1.WSGI WSGI的全称是Web Server Gateway Interface(Web服务器网关接口),它不是服务器.pyt ...

  3. super之mro列表牵引出c3算法

    目录 一:super的使用 二:super之mro列表牵引出c3算法 三:mro列表总结使用 一:super的使用 class Person(object): def __init__(self, n ...

  4. checklist 编写指南

    checklist 编写工具 checklist文档格式推荐使用思维导图.比如 MindMaster 和 processon.我喜欢用这些平台或者软件的思维导图大纲模式来编写 checklist. c ...

  5. ApacheCN Asp.NET 译文集 20211126 更新

    ASP.NET Core2 基础知识 零.前言 一.搭建舞台 二.控制器 三.视图 四.模型 五.验证 六.路由 七.RestBuy 八.添加功能.测试和部署 ASP.NET Core3 和 Angu ...

  6. Atcoder ARC-065

    ARC065(2020.8.3) A 尛你 \(\%\%\%\) B 翻译是错的,自闭了好久.先并查集将地铁连接的连通块联通,再枚举每条道路边判断是否在同一连通块即可. C 这翻译不知道在讲什么,建议 ...

  7. idea2020.1版本的maven项目报包不存在,找不到包错误

    错误描述 idea创建maven项目,导入依赖都是成功,但是运行就会报找不到对应jar包的错误 解决办法: File -> Settings -> 搜索maven -> 展开mave ...

  8. 抓包神器 tcpdump 使用介绍 (转)

    tcpdump 命令使用简介 简单介绍 tcpdump 是一款强大的网络抓包工具,运行在 linux 平台上.熟悉 tcpdump 的使用能够帮助你分析.调试网络数据. 要想使用很好地掌握 tcpdu ...

  9. visual studio版本 宏

    转载请注明来源:https://www.cnblogs.com/hookjc/ MSVC++ 12.0 _MSC_VER == 1800 (Visual Studio 2013) MSVC++ 11. ...

  10. Xcode 插件失效,启动崩溃解决

    升级6.4点击 Alcatraz PackageManager 崩溃解决 进入插件安装目录 cd ~/Library/Application\ Support/Developer/Shared/Xco ...