第一种:  通过继承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. 关于python 爬虫遇到的反盗链

    首先声明:目标网址是从别人案例里得到的,内容你懂的... 本来闲来无事,学习下爬虫的知识,遇到恶心的反盗链,好在目标网址防盗链简单,代码里注明了如何去查看目标网址的防盗检查: 防盗链原理 http标准 ...

  2. 信奥题库(OI题库)8月月赛T1题解 幂次数

    0.前置知识 分解质因数 快速幂(不必要) 1.思路 首先,我们知道一个正整数(设它为 \(a\) )一定能分解成这样的形式: \[a= \prod_{i\in N^*} p_i^{c_i} \] 其 ...

  3. Python 序列类型小结

    序列是python中最基本的数据结构. 序列中每一个元素都有其对应的索引,索引是从0开始,0,1,2......依次类推 python中的序列类型有:字符串str.列表list.元组tuple.Uni ...

  4. ApacheCN Linux 译文集 20211129 更新

    笨办法学 Linux 中文版 练习 0:起步 练习 1:文本编辑器,vim 练习 2:文本浏览器,少即是多 练习 3:Bash:Shell..profile..bashrc..bash_history ...

  5. iBooker 财务提升星球 2020.2~3 热门讨论

    前两天分享了一下关于我们个人的现金流,今天就以公司的角度去分- 我们技术人,如何开源增加我们的收入? 首先,我们对收入进行下- 热门股要不要买? 参考标准: 1. 时机 2. 泡沫 时- #老实人报# ...

  6. React Transition css动画案例解析

    实现React Transition Css动画效果 首先在项目工程中引入react-transition-group: npm install react-transition-group --sa ...

  7. JDBC工具包commons-dbutils的基本介绍

    感谢原文作者:simonXi-tech 原文链接:https://blog.csdn.net/simonforfuture/article/details/90480147 更多请查阅在线API文档: ...

  8. 创建spring boot项目并添加多个模块时,启动报 错误: 找不到或无法加载主类

          最近建个项目发现启动报,找不到或无法加载主类,想想肯定是自己配置出问题了,经过排查确实出问题了,(根pom中的bulid为移到子模块中去导致的),下面演示下正确的创建子模块的步奏 1. 创 ...

  9. Mysql批量删除和修改某个前缀的表

    1.批量删除某个前缀的表名,首先选出这些个表. select concat( 'drop table ', table_name, ';' ) from information_schema.tabl ...

  10. js实现网页中英文翻译

    1,html 2,metrics.js 3,需要 http://www.microsoftTranslator.com/ajax/v3/WidgetV3.ashx?siteData=ueOIGRSKk ...