持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第4天,点击查看活动详情
进程与线程
进程与线程的基本认识
进程(Process)
进程是程序的一次动态执行过程,它经历了从代码加载、执行、到执行完毕的一个完整过程;同时也是并发执行的程序在执行过程中分配和管理资源的基本单位,竞争计算机系统资源的基本单位。
线程(Thread)
线程可以理解为进程中的执行的一段程序片段,是进程的一个执行单元,是进程内可调度实体,是比进程更小的独立运行的基本单位,线程也被称为轻量级进程。
为什么会有线程
每个进程都有自己的地址空间,即进程空间,在网络或多用户换机下,一个服务器通常需要接收大量不确定数量用户的并发请求,为每一个请求都创建一个进程显然行不通,即使多进程可以提高硬件资源的利用率,但是进程的启动和销毁需要消耗大量的系统性能,从而导致程序的执行性能下降。所以为了进一步提升并发操作的处理能力,在进程的基础上又划分了多线程概念。
比如说看电影
看电影可以理解为实现了一个“进程”,而在看的时候,会同时听到声音,看到图片,这些都是多线程实现。
一个程序至少一个进程,一个进程至少一个线程。
多线程实现
在java中,如果要实现多线程,就必须依靠线程主体类,而java.lang.Thread是java中负责多线程操作类,只需继承Thread类,就能成为线程主体类,为满足一些特殊要求,也可以通过实现Runnable接口或者Callable接口来完成定义。
具体方式如下:
1.继承Thread类,重写run方法(无返回值)
2.实现Runnable接口,重写run方法(无返回值)
3.实现Callable接口,重写call方法(有返回值且可以抛出异常)
下面介绍几种
继承Thread类
实现方式
继承Thread类
重写run()方法
创建线程对象
调用start()方法启动
调用run方法会当成普通方法执行,只有调用start方法才是启动一个新的线程执行
优点
编码简单
缺点
是单继承,线程类继承Thread后,不能继承其他类,不便于扩展
实现Runnable接口
实现方式
定义一个线程任务类MyRunnable实现Runnable接口,重写run()方法
创建MyRunnable对象
把MyRunnable任务对象交给Thread线程对象处理
调用线程对象的start()方法启动线程
实现多线程(匿名内部类)
创建Runnable的匿名内部类对象
交给Thread处理
调用线程对象的start()启动线程
优点
实现了Runnale接口,可以继续继承和实现
缺点
线程有执行结果是不能直接返回
实现Callable、FutureTask接口
实现方式
创建Callable接口实现类,重写call()方法,封装
用FutureTask把Callable对象封装成线程任务对象
线程任务对象交给Thread处理,调用start()方法启动线程,执行任务
执行完毕后,通过FutureTask的get方法去获取任务执行的结果
优点
线程任务类只是实现接口,可以继续继承类和实现接口,扩展性强。 可以在线程执行完毕后去获取线程执行的结果。
缺点
编码复杂