目录
最近复习(学习)操作系统进程与线程,看着教材上满满当当的文字,顿时觉得枯燥无味,于是就想着自己实践一下,便学了学Java的多线程(b站狂神老师),果然比看书来的要明白啊,不过理论知识还是要从书中汲取的好。
多线程
线程简介
说起线程,那就不得不提一下进程,说到进程那又不得不说一下程序,那我们就来依次介绍下吧。
程序:指令和数据的有序集合,其本身没有任何运行的含义,是一个静态概念。
进程:是程序的一次执行过程,是一个动态概念。是系统资源分配的单位。
线程:是CPU调度和执行的单位(准确来说是内核级线程)。通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程。可以理解为“轻量级进程”。
一不小心又上车了,哈哈哈哈,狂神老师跟王道考研讲课都很有特点呀。
那为什么要引入 “ 线程 ”呢。
我们知道,在传统的程序中,进程是程序执行的最小单位,但是有的程序可能需要 “ 同时 ”做很多事,如果依次串行执行的话十分麻烦,因此引入了 “ 线程 ”,来增加并发度。
那引入线程机制之后,我们的程序使用起来是否真的便捷了呢,来看一看变化。
-
资源分配、调度
引入线程后,进程是资源分配的基本单位,线程是调度的基本单位(内核级线程),同一个进程内的线程共享该进程的资源环境。
-
并发性
引入线程后,各个线程之间也能并发执行,提升了并发度。
-
系统开销
如果是同一个进程内的线程切换,因为资源共享,所以不需要切换进程环境,系统开销变小。
如果不同进程间的线程切换,则仍然需要切换进程环境,开销与原来相同。
线程的属性
-
线程是处理机调度的单位。
-
多CPU计算机中,各个线程可占用不同的CPU。
-
每个线程都有一个线程ID、线程控制块(TCB,类似与进程的PCB)
-
线程也有就绪、阻塞、运行三种基本状态
-
线程几乎不拥有系统资源
-
同一个进程内的不同线程共享进程的资源
-
由于共享内存地址空间,同一进程的线程间通信无需系统干预。
线程的创建
-
继承Thread类
-
实现Runnable接口
-
实现Callable接口(目前不常用)
1.继承Thread类
不了解Thread类的小伙伴可以查看帮助文档哦。
通过帮助文档我们可以看到Thread类是继承了老祖宗类(Object类),并实现了Runnable接口
下面来看看它的构造方法
是不是有很多构造方法呢,不过我们目前掌握前两种就够啦。
纸上得来终觉浅,只停留在理论方面可不行,下面我们来手动创建一个线程。
-
自定义线程类继承Thread类
-
重写run()方法,编写线程执行体
-
创建线程对象,调用start()方法启动线程
这样我们的第一个线程就创建好啦,下面来看看运行效果吧。
是不是跟你想象的不太一样呢
再来思考一个问题,如果我们直接在主线程中调用run()方法,结果还会一样吗
来看看结果吧
哎,这次结果是不是不一样了呢,这次是先玩手机,后吃饭。
这就是我们要介绍的普通方法调用和多线程的区别。
2.实现Runnable接口
老样子,我们还是先来看看帮助文档
可以看到Runnable接口里只有一个run()方法,所以当我们不希望继承Thread类的其他方法时我们更推荐通过实现Runnable接口来创建线程。
实现Runnable
-
自定义线程类实现 Runnable 接口
-
实现 run()方法,编写线程执行体
-
创建线程对象,调用 start()方法启动线程
代理类对象是通过上文 Thread 类中第二个构造方法实现,我们自定义的线程是实现了 Runnable 接口的,所以可以通过 Thread 类的构造方法来调用 start()。
运行效果
怎么样,是不是也实现一边吃饭一边玩手机了呢,哈哈哈,吃饭时还是不要玩手机的好哦,以上例子请勿模仿。
看完了以上文章,是不是对线程有一个清晰的了解了呢,快去创建线程实验一下吧。