当前课程知识点:JAVA程序设计进阶 > 第二章 线程(中) > 2.6 线程的调度 > Video
这一节我们将介绍线程的调度
当多线程在运行的过程当中
JAVA虚拟机怎么来决定
哪个线程先运行
哪个线程后运行呢
这些就涉及到线程的调度机制
那线程的调度
主要依靠这个一种优先级
那为什么进行线程调度呢
由于在单CPU系统中
多个线程需要共享CPU
那在任何时间点
实际上只能有一个线程在运行
所以让谁运行
和先运行 后运行
这个事情的话
就要有个调度机制
所以我们控制多个线程
在同一个CPU上
以某种顺序运行
我们称之为线程调度
那JAVA虚拟机
它支持一种非常简单的
确定调度算法
叫做固定优先级算法
就是基于这个线程优先级
来进行调度
那实际上现在我们很多同学
你们使用的这个电脑
笔记本电脑
它实际上往往有多核
比如双核 四核
那如果操作系统做的好的话
是应该可以
让这些几何的这个CPU
都同时运行这个程序
那这时候这调度
有可能就是会更加丰富了
也就是我们那个
有可能两个CPU
都在运行我们的JAVA程序
那本身JAVA当中
这个是通过优先级来调度的
每一个线程都有个优先级
范围在1到10之间
如果我们在创建线程的时候
不设定它的优先级的话
那它缺省就是5
那如果我们是在线程A
运行过程中
创建的新的线程B
那你这个初创的这个线程
它和你这个原来的线程
就有同样的这个优先级
另外如果你A是个后台程序
那在A中创建线程B的话
B也是后台程序
当线程创建以后
我们都可以通过它的方法
setPriority来改变它的优先级
进而会影响到
它的这个线程调度过程
那在JAVA当中
它的线程调度器的话
是这个基于优先级
这个高的先运行
也就是说高优先级的线程
比低优先级的线程优先执行
那对于同优先级的线程
那JAVA的处理是随机的
我们的JAVA的线程执行
因为往往要受到
底层操作系统的支持
但是也许底层操作系统
它优先级它少10个
这样的话这个造成一些混乱
当然我们也可以通过
这个使用这个yield的方法
来去稍微改变一下
它的这个执行过程
yield方法主要作用是
把自己当前运行的线程暂停下来
把优先级
把线程让给同优先级的线程执行
当如果这时候不存在
同优先级的线程
那你还是你继续执行
我们只能基于效率
来考虑使用线程优先级
而不能依靠线程优先级
来保证这个算法的正确性
这里是一个图示了
也就是说我们在JAVA当中
有10个优先级
那每个优先级底下
会挂着好几个这个线程
比如我们这优先级为5的时候
底下有三个线程依次排队
优先级为10的底下
有线程4和线程5在排队
那根据我们现在这个结构的话
线程调度器
肯定会先调度线程4先执行
紧接着是调度线程5执行
然后其次才会是到线程1
线程2和线程3
那线程之间在运行的时候
怎么会变成一个
这个状态的这个切换呢
然后让它暂停运行呢
比如说有一个更高优先级的线程
它进入了就绪状态
那这时候我们当前这个线程
就必须让位于更高优先级的线程
那另外一种情况说
我们的线程运行过程中
由于输入输出受到了阻塞
或者自己调用了sleep方法休眠
或者自己调用了
wait方法等待某个变量
或者调用yield方法
让给其它同优先级的线程
那自己就会进入这个阻塞状态
那对于有些支持时间分片的系统
当时间片的时期满的时候
就可以进入下一轮的这种调度
那这种情况
有没有时间片的情况
取决于你操作系统
是不是支持这种方式的调度
下面我们看一个例子
我们打算创建两个
具有不同优先级的线程
然后它们的功能
都是从1递增到40万
然后每增加5万
我们就让它打印输出
我们看一下这个例子的代码
我们看它的主方法
主方法的第一行的话
这个构造了一个线程数组
runners有两个线程
然后通过循环来进行实例化
紧接着我们设置
第一个线程优先级为2
就是runners0 setPriority2
runners1.setpriority3
是第二个线程优先级为3
那在JAVA当中
就是优先级数字高的
它就优先级高
所以我们可以看出来
这个我们runners1它的优先级
比runners0要高
紧接着把这两个线程
调用它的start方法
让它们启动起来
那我们看这个每个线程
它的具体的功能是什么
class TestThread
extends Thread
然后它里面最主要的功能
我们看它的这个run方法
run方法里面
while tick小于40万
然后tick++是每次增加1
如果tick除以5万
它的余数是0
那我们就打印出这个
(英文)
它的tick的值是多少
然后循环完了以后
立刻调用yield方法
yield方法它是说放弃执行权
当然这个放弃执行权作用
是让这个JAVA线程调用去调用
和它同优先级的系统来执行
如果此时此刻
没有同优先级的线程存在的话
那这个线程它还继续执行
我们看一下这个执行结果
大家可以看到这个结果
里面优先级高的
这个第二个线程
它实际上是先执行
而且等它执行完了以后
才调度这个优先级低的线程
来这个执行
然后在这个执行过程当中
我们优先级高的这个线程
虽然调用了yield方法
去放弃cpu资源
但是由于yield方法
最后说是让位于
同优先级的这个线程
但那个时候并没有存在
同优先级的线程
所以这个我们的第一
这个第一号线程它还在运行
那我们再把上面的代码修改一下
看看一下效果
比如说我们在yield方法后面
增加了含sleep语句
让线程也暂时放弃一下
这个自己的运行
哪怕就是一毫秒
那这个时候线程0
也有机会被调度
这个线程调度器调度这个执行
那修改后的代码就是这样
也就是我们在yield方法后面
写一行try sleep1
然后catch什么什么Exception
好 那我们看一下
修改后的这个运行效果
大家可以看到
并不是这个编号为1的线程
都执行完了
再执行编号为0的线程
而是这里面
有交错执行的这个过程
那这里面重要的一个
这个原因就是
线程调用sleep方法
sleep方法是说我自己进入休眠
那一旦自己进入休眠的话
那它就我们线程调度器
有可能调度
我们第一优先级的这个线程
也就是说对高优先级的
这个线程的话
如果要让出自己的执行权限的话
就要调用sleep方法
然后给其它第一优先级
这个线程以机会
如果高优先级的线程
仅仅只是调用了yield方法
那它并不一定能
它并不能给我们低优先级线程
以执行的机会
它只给了它同优先级的线程
以执行的这个机会
这一节我们通过介绍
JAVA的优先级
来实现线程调度的机制
下面总结一下
本章的学习内容
在本章当中
我们学习了线程同步的方法
以及线程的生命周期
还有线程的优先级等等内容
希望通过本章的学习
让大家掌握线程同步的方法
理解线程优先级的概念
以及基于优先级的线程调度
这些都是JAVA线程的重要内容
希望各位同学好好学习
好好掌握
-1.0 导学
--Video
-1.1 线程的基本概念
--Video
-1.1 线程的基本概念--作业
-1.2 通过Thread类创建线程
--Video
-1.2 通过Thread类创建线程--作业
-1.3 线程的休眠
--Video
-1.3 线程的休眠--作业
-1.4 Thread类详解
--Video
-1.5 通过Runnable接口创建线程
--Video
-1.5 通过Runnable接口创建线程--作业
-1.6 线程内部的数据共享
--Video
-2.0 导学
--Video
-2.1 线程同步的思路
--Video
-2.2 线程同步的实现方式—Synchronization
--Video
-2.3 线程的等待与唤醒
--Video
-2.4 后台进程
--Video
-2.5 线程的生命周期与死锁
--Video
-2.6 线程的调度
--Video
-3.0 导学
--Video
-3.1 线程安全与线程兼容与对立
--Video
-3.2 线程的安全实现-互斥同步
--Video
-3.3 线程的安全实现-非阻塞同步
--Video
-3.4 线程的安全实现-无同步方案
--Video
-3.5 锁优化
--Video
-4.0 导学
--Video
-4.1 URL对象
--Video
-4.2 URLConnection对象
--Video
-4.3 Get请求与Post请求
--Video
-4.4 Socket通信原理
--Video
-4.5 Socket通信实现
--Video
-5.0 导学
--Video
-5.1 Socket 多客户端通信实现
--Video
-5.2 数据报通信
--Video
-5.3 使用数据报进行广播通信
--Video
-5.4 网络聊天程序
--Video
-6.0 导学
--Video
-6.1 Java虚拟机概念
--Video
-6.2 Java虚拟机内存划分
--Video
-6.3 Java虚拟机类加载机制
--Video
-6.4 判断对象是否存活算法及对象引用
--Video
-6.5 分代垃圾回收
--Video
-6.6 典型的垃圾收集算法
--Video
-6.7典型的垃圾收集器
--Video
-7.0 导学
--Video
-7.1 集合框架与ArrayList
--Video
-7.2 LinkedList
--Video
-7.3 HashMap与HashTable
--Video
-7.4 TreeMap与LinkedHashMap
--Video
-7.5 HashSet
--Video
-8.0 导学
--Video
-8.1 Java反射机制
--Video
-8.2 Java静态代理
--Video
-8.3 Java动态代理
--Video
-8.4 Java 反射扩展-jvm加载类原理
--Video
-8.5 Java进阶课程总结
--Video