上节讲了基础概念,本章正式进入线程专题,对基础薄弱的同学可以好好看本章!!

1、Thread匿名子类

我们可以通过下面的代码来直接创建一个线程。

// 构造方法的参数是给线程指定名字,推荐
Thread t1 = new Thread("t1") {@Override// run 方法内实现了要执行的任务public void run() {log.debug("hello");}
};
t1.start();

需要注意下:

  • 创建线程是不是立马就执行?

当然不是,当调用t1.start()的时候,虚拟机先执行main方法,所以会有main线程去执行代码,而执行到Thread的时候,发现要开辟一个线程,于是会创建一个新线程,等待cpu分配时间片去调度,而start方法两个作用:新创建个线程+此线程进入就绪状态等待被执行

2、实现Runnable接口

我们也可以通过这个方式去创建线程:

Runnable runnable = new Runnable() {public void run(){// 要执行的任务}
};
// 创建线程对象
Thread t = new Thread( runnable );
// 启动线程
t.start(); 

和第一种方式相比,其实有很大的不同,这种方式是【任务】和【线程】分开,Runnable实际在这里表示可运行的任务,比如下面的代码执行:Thread一定是要有的,而Thread的有参构造,传入当前要执行的任务对象包给这个线程去执行,同时也可以给予开辟的线程名称。

在Java8的Lambda表达式中,可以简化写法,这里我不多说Lambda表达式自行了解。

我们分析Thread的源码,理清它与 Runnable 的关系,当Runnable对象不为空,Thread构造方法传递Runnable对象,底层会调用Runnable对象的run方法进行任务的创建。

而直接new Thread的方式实际就是创建一个子类对象,重写父类的run方法,最终会调用子类中的run方法,所以在底层执行中,走的都是底层的run方法。

区别在于:

new Thread是把线程和任务合并在了一起

        实现Runnable是把线程和任务分开了,用 Runnable 更容易与线程池等高级 API 配合

        用 Runnable 让任务类脱离了 Thread 继承体系,更灵活。

3、FutureTask配合Thread

先看下FutureTask的结构:很明显实现了Runnable接口,也是个任务对象;另外多了一个Future接口,用来返回任务的执行相关信息的。

由于Runnable的run方法是void类型,并不能在两个线程中把一个结果传递给另一个线程,而Future接口中的get方法是可以用来返回结果,怎么用这个FutureTask创建一个任务对象呢?

因为FutureTask<V>是个泛型,且get方法返回也是个泛型,在FutureTask的构造中传递参数是Callable接口;

其中的call方法是具备返回值的。

于是我们可以这么写,这里有个比较关键的一个点,当主线程运行到get的时候,会阻塞等待,直到这个task3执行完后返回了,主线程才可以拿到task3执行后返回的结果并输出。

// 创建任务对象
FutureTask<Integer> task3 = new FutureTask<>(() -> {log.debug("hello");return 100;
});
// 参数1 是任务对象; 参数2 是线程名字,推荐
new Thread(task3, "t3").start();
// 主线程阻塞,同步等待 task 执行完毕的结果
Integer result = task3.get();
log.debug("结果是:{}", result);

4、思考为什么有了Thread还出现Runnable?

我觉得这个问题会有很多基础不扎实的同学搞不明白,甚至工作很多年的都会是一脸蒙蔽,我这里就说说我个人的观点:

首先Thread出现的时候,在使用方面,通过继承的方式去重写父类Thread的run方法,达到线程执行逻辑的目的,那么如果一个类A已经继承过了其他的父类B,你再想去让某个线程在这个类执行里面部分代码,你该怎么做?

要么你选择单独开个类C,继承Thread,然后类A的逻辑cp一份到这个C类上走下Thread.start方法;

要么改逻辑?不现实吧,那么Runnable出现,这个时候解决了这个问题,没错,Java中不能多继承,只能单继承的机制,但是可以多实现,好了我可以选择让当前这个A类implements Runanble,并且可以重写里面的run方法,而要执行的代码逻辑,是不是可以抽出一个方法,并且在这个run中调用这个方法就可以了?这是一点

还有就是,Thread t1 = new Thread子类,这个子类里会复写父类的方法,完成业务逻辑,发现没有,这个线程只能干这个事情,没法做到和其他线程共享处理某个任务,不信你就可以试试看。如果我想做多个线程处理同一个业务逻辑,我无法做到,比如,多个窗口卖票!

那么有了Runnable的好处,我可以定义某个任务,这个任务就是去扣除票的,那么Thread提供了相关的Runnable的构造,就表示可以有多个Thread执行这个任务,就可以达到多个线程执行相同的任务效果,至于其中的临界资源控制,不在这个范围中。

所以,好处一定是存在,但是认不认识到,那是另一个事情。

创建线程的三种主要方式就介绍到这。后面剖析线程原理

并发编程基础篇——第二章(如何创建线程)相关推荐

  1. 并发编程基础篇——第一章(并发相关基础概念理解)

    其实讲到并发编程,有时候会问自己为什么要去做这些知识的积累和沉淀,可能我们做业务的在职业生涯里,并不会经常使用到这些所谓的多线程编程,顶多可能开一个线程,去执行个任务,又或者通过定时器触发某个业务,实 ...

  2. Java编程基础篇第二章

    关键字 概述:被Java语言赋予特定含义的单词. 特点:组成关键字的字母全部为小写字母. 标识符 概述:给类,接口,包,方法,常量起名字时的字符序列 组成规则:英文大小写字母,数字,$和- 命名规则. ...

  3. WPF编程基础入门 ——— 第二章 XAML

    XAML 简述 XAML(eXtensible Application Markup Language,可扩展应用程序标记语言)是微软公司创建的一种新的描述性语言,用于搭建应用程序用户界面.XAML实 ...

  4. java并发编程入门_探讨一下!Java并发编程基础篇一

    Java并发编程想必大家都不陌生,它是实现高并发/高流量的基础,今天我们就来一起学习这方面的内容. 什么是线程?什么是进程?他们之间有什么联系? 简单来说,进程就是程序的一次执行过程,它是系统进行资源 ...

  5. 鸟哥的Linux私房菜(基础篇)-第二章、 Linux 如何学习(二.3. 有心朝Linux作业系统学习者的学习态度)

    第二章. Linux 如何学习 最近更新日期:2009/08/06 3. 有心朝Linux作业系统学习者的学习态度 3.1 从头学习Linux基础 3.2 选择一本易读的工具书 3.3 实作再实作 3 ...

  6. 鸟哥的Linux私房菜(基础篇)-第二章、 Linux 如何学习(二.2. 鸟哥的Linux苦难经验全都录)

    第二章. Linux 如何学习 最近更新日期:2009/08/06 2. 鸟哥的Linux苦难经验全都录 2.1 鸟哥的Linux学习之路 2.2 学习心态的分别 2.3 X window的学习 鸟哥 ...

  7. Java语言程序设计(基础篇) 第二章

    第二章 基本程序设计 2.2 编写简单的程序 1.变量名尽量选择描述性的名字(descriptive name). 2.实数(即带小数点的数字)在计算机中使用一种浮点的方法来表示.因此,实数也称为浮点 ...

  8. 鸟哥的Linux私房菜(基础篇)-第二章、 Linux 如何学习(二.5. 重点回顾)

    第二章. Linux 如何学习 最近更新日期:2009/08/06 5. 重点回顾 6. 本章习题 7. 针对本文的建议:http://phorum.vbird.org/viewtopic.php?t ...

  9. 鸟哥的Linux私房菜(基础篇)-第二章、 Linux 如何学习(二.4. 鸟哥的建议(重点在solution的学习))

    第二章. Linux 如何学习 最近更新日期:2009/08/06 4. 鸟哥的建议(重点在solution的学习) 鸟哥的建议(重点在Solution的学习): 除了上面的学习建议之外,还有其他的建 ...

最新文章

  1. 第十二周 11.15-11.21
  2. c语言调用oracle函数返回值吗,C语言通过值和引用函数
  3. maven升级遇到的疑惑
  4. 前端笔记-使用JavaScript防止空表单提交
  5. servlet ---- servlet入门
  6. ORACLE1.8-序列
  7. 递推DP URAL 1119 Metro
  8. MVPArms官方快速组件化方案开源,来自5K star的信赖
  9. faster rcnn 计算mAP
  10. 计算机恢复出厂设置xp,电脑xp一键恢复出厂设置
  11. git基于master创建新分支
  12. 如何利用R语言处理 缺失值 数据
  13. 《APP开发》APP规范实例-详细的UI设计方法
  14. The Complete Guide To Rooting Any Android Phone
  15. 互联网快讯:华虹虹芯基金正式发起成立;极米高性能投影产品获用户青睐;中国电信联手钉钉研发“天翼钉”
  16. win10下的msys2开发环境搭建
  17. 初学Java(一)Java介绍
  18. 亚马逊旺季前的狂风暴雨
  19. 一套开源免费的OA办公管理系统源码,带小程序、生成APP
  20. java 静态分析_静态代码分析与代码质量安全

热门文章

  1. LeetCode刷题-7
  2. GPT-3:现实版的“贾维斯”?还是真「人工」智能?
  3. 看完 50000 张专辑封面,AI 设计师开始疯狂输出
  4. 机器学习新闻综述:2019年AI领域不得不看的6篇文章
  5. 英特尔发布oneAPI软件计划及beta产品,面向异构计算提供统一可扩展的编程模型
  6. 18段代码带你玩转18个机器学习必备交互工具
  7. 物联网成网络安全防护新重点!
  8. AI 一分钟 | 特斯拉科技创新中心落户北京;麻省理工开发透视技术
  9. 无人驾驶汽车系统入门——基于Frenet优化轨迹的无人车动作规划方法
  10. 2021 年技术 5 大趋势