在线客服
扫描二维码
下载博学谷APP扫描二维码
关注博学谷微信公众号
Java支持多线程编程,因此用Java编写的应用程序可以同时执行多个任务。Java的多线程机制使用起来非常方便,用户只需关注程序细节的实现,而不用担心后台的多任务系统。本文将为大家讲解有关Java多线程的基础知识,主要内容有多线程的概念、创建、优势和生命周期。
1、什么是多线程
在早期的计算机中时没有操作系统的,计算机开启后只能执行一个程序,直到结束。操作系统的出现使得计算机可以同时执行多个程序,操作系统为每个程序分配不同的进程,每个进程拥有独立的句柄、资源等,使得计算机可以同时执行多个程序。但是进程的创建和销毁耗费的代价太大,因此衍生出线程的概念。允许在一个进程中创建多个线程,这些线程共享进程的资源,并且每个线程拥有自己独立的程序计数器、线程局部变量等资源。线程也被称为进程的轻量型运动实体。
2、创建多线程和启动
(1)继承Thread类创建线程类
通过继承Thread类创建线程类的具体步骤和具体代码如下:
定义一个继承Thread类的子类,并重写该类的run()方法;
创建Thread子类的实例,即创建了线程对象;
调用该线程对象的start()方法启动线程。
class SomeThead extends Thraad {
public void run() {
//do something here
}
}
public static void main(String[] args){
SomeThread oneThread = new SomeThread();
步骤3:启动多线程:
oneThread.start();
}
(2)实现Runnable接口创建线程类
通过实现Runnable接口创建线程类的具体步骤和具体代码如下:
定义Runnable接口的实现类,并重写该接口的run()方法;
创建Runnable实现类的实例,并以此实例作为Thread的target对象,即该Thread对象才是真正的线程对象。
class SomeRunnable implements Runnable {
public void run() {
//do something here
}
}
Runnable oneRunnable = new SomeRunnable();
Thread oneThread = new Thread(oneRunnable);
oneThread.start();
(3)通过Callable和Future创建线程
通过Callable和Future创建线程的具体步骤和具体代码如下:
创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。
创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。
使用FutureTask对象作为Thread对象的target创建并启动新线程。
调用FutureTask对象的get()方法来获得子线程执行结束后的返回值其中,Callable接口(也只有一个方法)定义如下:
public interface Callable {
V call() throws Exception;
}
步骤1:创建实现Callable接口的类SomeCallable(略);
步骤2:创建一个类对象:
Callable oneCallable = new SomeCallable();
步骤3:由Callable创建一个FutureTask对象:
FutureTask oneTask = new FutureTask(oneCallable);
注释: FutureTask是一个包装器,它通过接受Callable来创建,它同时实现了 Future和Runnable接口。
步骤4:由FutureTask创建一个Thread对象:
Thread oneThread = new Thread(oneTask);
步骤5:启动线程:
oneThread.start();
3、多线程的优势
多线程的出现带来很多的好处:
(1)发挥多核处理器的性能:在多喝处理器上执行单线程任务是对多核的浪费,因为总有核心在空闲着,多线程的出现能充分发挥多核的优势。
(2)化整为零:往往在一个复杂的应用中包含许多不同类型的任务,将这些不同类型的任务分配给不同的线程去执行会比将其混在同一个线程中去执行要好,因为每个线程更加的简单清晰,更容易测试等。
(3)异步事件处理:当一个线程处理的任务遇到阻塞时如IO阻塞,cpu可以调度其他线程去执行而不是在那傻傻的等到IO结束在执行其他任务。
(5)更好的用户体验:当多个用户像你的服务发送请求时,你一个线程依次执行任务会使得排在后面的用户等待时间过长得不到响应,带来不好的体验。但使用多个线程可以让每个用户都能很快的得到响应(尽管这不能高执行速度),用户会觉得自己的请求正在被处理,获得更好的体验。
4、多线程的生命周期
(1)新建状态
用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于新生状态。处于新生状态的线程有自己的内存空间,通过调用start方法进入就绪状态(runnable)。
注意:不能对已经启动的线程再次调用start()方法,否则会出现Java.lang.IllegalThreadStateException异常。
(2)就绪状态
处于就绪状态的线程已经具备了运行条件,但还没有分配到CPU,处于线程就绪队列(尽管是采用队列形式,事实上,把它称为可运行池而不是可运行队列。因为cpu的调度不一定是按照先进先出的顺序来调度的),等待系统为其分配CPU。等待状态并不是执行状态,当系统选定一个等待执行的Thread对象后,它就会从等待执行状态进入执行状态,系统挑选的动作称之为“cpu调度”。一旦获得CPU,线程就进入运行状态并自动调用自己的run方法。
提示:如果希望子线程调用start()方法后立即执行,可以使用Thread.sleep()方式使主线程睡眠一伙儿,转去执行子线程。
(3)运行状态
处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
处于就绪状态的线程,如果获得了cpu的调度,就会从就绪状态变为运行状态,执行run()方法中的任务。如果该线程失去了cpu资源,就会又从运行状态变为就绪状态。重新等待系统分配资源。也可以对在运行状态的线程调用yield()方法,它就会让出cpu资源,再次变为就绪状态。
注: 当发生如下情况是,线程会从运行状态变为阻塞状态:
①、线程调用sleep方法主动放弃所占用的系统资源
②、线程调用一个阻塞式IO方法,在该方法返回之前,该线程被阻塞
③、线程试图获得一个同步监视器,但更改同步监视器正被其他线程所持有
④、线程在等待某个通知(notify)
⑤、程序调用了线程的suspend方法将线程挂起。不过该方法容易导致死锁,所以程序应该尽量避免使用该方法。
当线程的run()方法执行完,或者被强制性地终止,例如出现异常,或者调用了stop()、desyory()方法等等,就会从运行状态转变为死亡状态。
(4)阻塞状态
处于运行状态的线程在某些情况下,如执行了sleep(睡眠)方法,或等待I/O设备等资源,将让出CPU并暂时停止自己的运行,进入阻塞状态。 在阻塞状态的线程不能进入就绪队列。只有当引起阻塞的原因消除时,如睡眠时间已到,或等待的I/O设备空闲下来,线程便转入就绪状态,重新到就绪队列中排队等待,被系统选中后从原来停止的位置开始继续运行。有三种方法可以暂停Threads执行:
(5)死亡状态
当线程的run()方法执行完,或者被强制性地终止,就认为它死去。这个线程对象也许是活的,但是,它已经不是一个单独执行的线程。线程一旦死亡,就不能复生。 如果在一个死去的线程上调用start()方法,会抛出java.lang.IllegalThreadStateException异常。
以上就是Java多线程的基础知识讲解,大家都了解了吗?这些基础知识大家都必须掌握,如果还有什么不明白的,可以报博学谷的Java课程,会有线上的专业老师为大家答疑解惑。
— 申请免费试学名额 —
在职想转行提升,担心学不会?根据个人情况规划学习路线,闯关式自适应学习模式保证学习效果
讲师一对一辅导,在线答疑解惑,指导就业!
相关推荐 更多
Dubbox分布式服务框架全面学习
谈到分布式服务框架Dubbox,我们不得不提到它的前身——阿里巴巴开源项目Dubbo 。因为后面当当网对Dubbo进行了优化并维护,所以才有了现在的Dubbox。Dubbox的优势不用多说,相信大家都或多或少有所了解,它能提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案。本篇文章将着重给大家介绍Dubbox分布式服务框架的学习教程,感兴趣的朋友就一起来看看吧!
4758
2019-12-09 15:26:52
学习Java的好书有哪些?Java书籍清单
Java书籍是程序员学习提升技能的重要学习渠道,通过书籍Java程序员可以学习当前流行、重要的相关技能。经典的书经受时间的考验,随着岁月的流逝变得越来越重要,让我们不断的学习和进步。
4493
2020-02-12 16:23:27
Redis选择单线程模型的原因分析
双线程的程序可以支持每秒几百万的请求量,众所周知,Redis 作为被广泛使用的内存数据库偏偏选择了单线程模型,这又是为什么呢?其实简单概括起来主要有以下三个原因,方便维护,可以并发的处理任务以及双线程不能解决Redis的性能瓶颈。下面我们来仔细分析一下Redis选择单线程模型的原因。
4788
2020-03-10 18:41:44
Java学习看什么书比较好?
虽然视频学习资料是许多人入门或提升编程的首选,但是书籍材料对学习者来讲,也是必须要看的。尤其对于处在不同能力阶段的人来讲,选择适合自己学习的书尤为重要。那么,Java学习看什么书比较好呢?下面本文会按照基础入门和进阶提升两个方面,推荐适合各个能力阶段学习的书籍。
4171
2020-07-10 10:40:20
Java初学者须知编码规范
现代软件行业的高速发展对开发者的综合素质要求越来越高, 因为不仅是编程知识点,其它维度的知识点也会影响到软件的最终交付质量。比如: 数据库的表结构和索引设计缺陷可能带来软件上的架构缺陷或性能风险; 工程结构混乱导致后续维护艰难;没有鉴权的漏洞代码易被黑客攻击等。 有些人觉得编码规范不重要,其实是大错特错。下面是关于代码格式的一些编码规范,都是Java初学者非常容易忽视的细节:
4706
2020-08-10 16:09:38