java创建线程的四种方法
第一种: 通过继承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创建线程的四种方法的更多相关文章
- Java创建线程的四种方式
Java创建线程的四种方式 1.继承Thread类创建线程 定义Thread类的子类,并重写该类的run方法,run()方法的内容就是该线程执行的内容 创建Thread子类的实例,即创建了线程对象. ...
- java创建线程的三种方法
这里不会贴代码,只是将创建线程的三种方法做个笼统的介绍,再根据源码添加上自己的分析. 通过三种方法可以创建java线程: 1.继承Thread类. 2.实现Runnable接口. 3.实现Callab ...
- Java多线程——之一创建线程的四种方法
1.实现Runnable接口,重载run(),无返回值 package thread; public class ThreadRunnable implements Runnable { public ...
- Java 创建线程的两种方法
Java提供了线程类Thread来创建多线程的程序.其实,创建线程与创建普通的类的对象的操作是一样的,而线程就是Thread类或其子类的实例对象.每个Thread对象描述了一个单独的线程.要产生一个线 ...
- Java创建线程的两种方法
大多数情况,通过实例化一个Thread对象来创建一个线程.Java定义了两种方式: 实现Runnable 接口: 可以继承Thread类. 下面的两小节依次介绍了每一种方式. 实现Runnable接口 ...
- Java 创建线程的3种方法及各自优势
1. 继承 Thread 类,然后调用 start 方法. class MyThread extends Thread { //重写run方法,线程运行后,跑的就是run方法 public void ...
- java 创建线程的三种方法Callable,Runnable,Thread比较及用法
转自:http://www.chinaitlab.com/Java/line/942440.html 编写多线程程序是为了实现多任务的并发执行,从而能够更好地与用户交互.一般有三种方法,Thread, ...
- Java创建线程的三种方法比较
一般有三种方法,Thread,Runnable,Callable. Runnable和Callable的区别 (1)Callable规定的方法是call(),Runnable规定的方法是run(). ...
- 区分JAVA创建线程的几种方法
1. start()和run() 通过调用Thread类的start()方法来启动一个线程,这时此线程是处于就绪状态,并没有运行.然后 通过此Thread类调用方法run()来完成其运行操 ...
随机推荐
- Nginx请求连接限制
目录 Nginx的请求限制 HTTP协议的连接与请求 连接限制 配置示例 做个演示: 请求限制 配置示例 基本指令 limit_req_zone limit_req zone 做个演示: Nginx的 ...
- Java多线程专题1: 并发与并行的基础概念
合集目录 Java多线程专题1: 并发与并行的基础概念 什么是多线程并发和并行? 并发: Concurrency 特指单核可以处理多任务, 这种机制主要实现于操作系统层面, 用于充分利用单CPU的性能 ...
- Java多线程专题2: JMM(Java内存模型)
合集目录 Java多线程专题2: JMM(Java内存模型) Java中Synchronized关键字的内存语义是什么? If two or more threads share an object, ...
- String 不可变
String 源码,String 的修饰符是 final String 采用的是共享模式,被放进常量池 String strA = "abc"; String strB = &qu ...
- 如何在pyqt中实现亚克力磨砂效果的QLabel
前言 Windows10 在 UWP 应用中支持亚克力画刷,可以在部件的底部绘制亚克力效果的背景图.下面我们使用 QLabel 来模拟这个磨砂过程. 实现方法 MSDN 文档中介绍了亚克力材料的配方, ...
- Lesson4——Pandas DataFrame结构
pandas目录 思维导图 1 简介 DataFrame 是 Pandas 的重要数据结构之一,也是在使用 Pandas 进行数据分析过程中最常用的结构之一. 2 认识DataFrame结构 Data ...
- 掌握这些常用Linux命令,一起提升工作效率
开始上班了,新一年的奋斗的之路启程了,要继续[奔赴山海,奔赴热爱]. 汪国真在<热爱生命>这首诗中写到:既然选择了远方,便只顾风雨兼程.技术上还是持续精进和学习,远方虽远,要迈开脚步,一步 ...
- NFS(Network File System)即网络文件系统 (转)
第1章 NFS介绍 1.1 NFS服务内容的概述 □ RPC服务知识概念介绍说明,以及RPC服务存在价值(必须理解掌握) □ NFS服务工作原理讲解(必须理解掌握) □ NFS共享文件系统使用原理讲解 ...
- xshell脚本之条件语句
xshell脚本之条件语句 1.test命令: 如果test命令中列出的条件成立,test命令就会退出并返回状态码0, 如果条件不成立,test命令就会退出并返回非零的退出状态码,这使得if-then ...
- Arch Linux遇到的坑(下)
明天就要开学,终于赶忙又熟悉了新环境的用法,现在已经基本满足了日常需求,再记录一些坑-. 电脑没有声音 因为上次离奇的自己好了,我就没有再管了,但是后来使用chrome的时候还是没有声音,我就用了图形 ...