并发编程基础篇——第二章(如何创建线程)
上节讲了基础概念,本章正式进入线程专题,对基础薄弱的同学可以好好看本章!!
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执行这个任务,就可以达到多个线程执行相同的任务效果,至于其中的临界资源控制,不在这个范围中。
所以,好处一定是存在,但是认不认识到,那是另一个事情。
创建线程的三种主要方式就介绍到这。后面剖析线程原理
并发编程基础篇——第二章(如何创建线程)相关推荐
- 并发编程基础篇——第一章(并发相关基础概念理解)
其实讲到并发编程,有时候会问自己为什么要去做这些知识的积累和沉淀,可能我们做业务的在职业生涯里,并不会经常使用到这些所谓的多线程编程,顶多可能开一个线程,去执行个任务,又或者通过定时器触发某个业务,实 ...
- Java编程基础篇第二章
关键字 概述:被Java语言赋予特定含义的单词. 特点:组成关键字的字母全部为小写字母. 标识符 概述:给类,接口,包,方法,常量起名字时的字符序列 组成规则:英文大小写字母,数字,$和- 命名规则. ...
- WPF编程基础入门 ——— 第二章 XAML
XAML 简述 XAML(eXtensible Application Markup Language,可扩展应用程序标记语言)是微软公司创建的一种新的描述性语言,用于搭建应用程序用户界面.XAML实 ...
- java并发编程入门_探讨一下!Java并发编程基础篇一
Java并发编程想必大家都不陌生,它是实现高并发/高流量的基础,今天我们就来一起学习这方面的内容. 什么是线程?什么是进程?他们之间有什么联系? 简单来说,进程就是程序的一次执行过程,它是系统进行资源 ...
- 鸟哥的Linux私房菜(基础篇)-第二章、 Linux 如何学习(二.3. 有心朝Linux作业系统学习者的学习态度)
第二章. Linux 如何学习 最近更新日期:2009/08/06 3. 有心朝Linux作业系统学习者的学习态度 3.1 从头学习Linux基础 3.2 选择一本易读的工具书 3.3 实作再实作 3 ...
- 鸟哥的Linux私房菜(基础篇)-第二章、 Linux 如何学习(二.2. 鸟哥的Linux苦难经验全都录)
第二章. Linux 如何学习 最近更新日期:2009/08/06 2. 鸟哥的Linux苦难经验全都录 2.1 鸟哥的Linux学习之路 2.2 学习心态的分别 2.3 X window的学习 鸟哥 ...
- Java语言程序设计(基础篇) 第二章
第二章 基本程序设计 2.2 编写简单的程序 1.变量名尽量选择描述性的名字(descriptive name). 2.实数(即带小数点的数字)在计算机中使用一种浮点的方法来表示.因此,实数也称为浮点 ...
- 鸟哥的Linux私房菜(基础篇)-第二章、 Linux 如何学习(二.5. 重点回顾)
第二章. Linux 如何学习 最近更新日期:2009/08/06 5. 重点回顾 6. 本章习题 7. 针对本文的建议:http://phorum.vbird.org/viewtopic.php?t ...
- 鸟哥的Linux私房菜(基础篇)-第二章、 Linux 如何学习(二.4. 鸟哥的建议(重点在solution的学习))
第二章. Linux 如何学习 最近更新日期:2009/08/06 4. 鸟哥的建议(重点在solution的学习) 鸟哥的建议(重点在Solution的学习): 除了上面的学习建议之外,还有其他的建 ...
最新文章
- 第十二周 11.15-11.21
- c语言调用oracle函数返回值吗,C语言通过值和引用函数
- maven升级遇到的疑惑
- 前端笔记-使用JavaScript防止空表单提交
- servlet ---- servlet入门
- ORACLE1.8-序列
- 递推DP URAL 1119 Metro
- MVPArms官方快速组件化方案开源,来自5K star的信赖
- faster rcnn 计算mAP
- 计算机恢复出厂设置xp,电脑xp一键恢复出厂设置
- git基于master创建新分支
- 如何利用R语言处理 缺失值 数据
- 《APP开发》APP规范实例-详细的UI设计方法
- The Complete Guide To Rooting Any Android Phone
- 互联网快讯:华虹虹芯基金正式发起成立;极米高性能投影产品获用户青睐;中国电信联手钉钉研发“天翼钉”
- win10下的msys2开发环境搭建
- 初学Java(一)Java介绍
- 亚马逊旺季前的狂风暴雨
- 一套开源免费的OA办公管理系统源码,带小程序、生成APP
- java 静态分析_静态代码分析与代码质量安全