JAVA抢占式线程调度的问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA抢占式线程调度的问题相关的知识,希望对你有一定的参考价值。
以下程序为例:
public class ThreadTerminate
public static void main(String args[])/*throws Exception*/
int i = 0;
Hello h = new Hello();
Thread t = new Thread(h);
t.setPriority(Thread.MAX_PRIORITY);
t.start();
System.out.println("Please stop saying Hello and say good morning!");
h.stopRunning();
while(i<5)System.out.println("Good Moring"+ i++);
class Hello implements Runnable
int i=0;
private boolean timeToQuit = false;
public void run()
while(!timeToQuit)
System.out.println("Hello" + i++);
try
if(i%2==1)
Thread.sleep(1000000000);
catch(Exception e)
public void stopRunning()
timeToQuit = true;
运行结果:
please stop saying hello and say good morning!
hello0
Good Morning0
Good Morning1
Good Morning2
Good Morning3
Good Morning4
问题:1、主线程在占用CPU的时候线程 t 为什么可以把主线程从CPU赶出来?那是不是只要有多个线程处于可运行态,就可以在当前线程运行的任何时候插进去把当前线程挤出CPU?
2、如果是因为线程 t 的优先级最高,那么运行结果为什么不是
hello0
please stop saying hello and say good morning!
Good Morning0
Good Morning1
Good Morning2
Good Morning3
Good Morning4
小白啊,谢大神讲清晰点
2即使线程t的优先级高,在调用start时,也不会保证线程已经真实的启动。os只是把他放到了线程队列中去排队。而当前线程继续执行。 参考技术A 多线程是没有啥说法是说某个线程具有优先级,都是由CPU随机的让某一个线程在一个时间段里面运行。而线程有个特定的叫计数器的东西,这个东西是控制每个线程在运行后,将控制权交出去后又得到时,不会运行出错,所以你可以试试多写几个线程试一下结果。
多说一句,main方法你也知道是主线程,就像老大没带头,小弟会动吗?所以要等main运行完了子线程才开始运行,你可以多些几个线程看看子线程是不是这样的 参考技术B cpu是在不断切换执行任务的,priority高的获得cpu运行时间的概率高,并不意味着能把低的完全挤掉,执行是有随机性的
Java线程调度及相关函数
文章目录
Java线程调度
线程调度
-
抢占式调度模型:
那个线程的优先级比较高,抢到的CPU时间片的概率就高一些/多一些。
java采用的就是抢占式调度模型。 -
均分式调度模型:
平均分配CPU时间片。每个线程占有的CPU时间片时间长度一样。
平均分配,一切平等。
有一些编程语言,线程调度模型采用的是这种方式。
相关方法
线程实例方法:
void setPriority(int newPriority); // 设置线程的优先级
int getPriority(); // 获取线程优先级
注意:
- 最低优先级1
- 默认优先级是5
- 最高优先级10
优先级比较高的获取CPU时间片可能会多一些。(但也不完全是,大概率是多的)。
void join(); // 让一个线程等待另一个线程完成的方法
当在某个程序执行流中调用其他线程的join()方法时,调用线程将被阻塞,直到被join()方法加入的join线程执行完为止。
join()方法通常由使用线程的程序调用,以将大问题划分成许多小问题,每个小问题分配一个线程。当所有的小问题都得到处理后,再调用主线程来进一步操作。
线程类静态方法:
static void yield(); // 让位方法
暂停当前正在执行的线程对象,并执行其他线程
yield()方法不是阻塞方法。让当前线程让位,让给其它线程使用。yield()方法的执行会让当前线程从“运行状态”回到“就绪状态”。
注意:在回到就绪之后,有可能还会再次抢到,然后过了很短时间就又运行了,所以可能会出现看起来像没调用yield()一样。
代码案例
设置线程优先级
package com.yyl.threadTest;
class MyThread extends Thread
@Override
public void run()
// 获取线程优先级
//System.out.println(Thread.currentThread().getName() + "线程的默认优先级:" + Thread.currentThread().getPriority());
for (int i = 0; i < 10000; i++)
System.out.println(Thread.currentThread().getName() + "-->" + i);
public class ThreadScheduling
public static void main(String[] args)
// 设置主线程的优先级为1
Thread.currentThread().setPriority(1);
// 获取当前线程对象,获取当前线程的优先级
Thread currentThread = Thread.currentThread();
Thread t = new Thread(new MyThread());
t.setPriority(10);
t.setName("t");
t.start();
// 优先级较高的,只是抢到的CPU时间片相对多一些。
// 大概率方向更偏向于优先级比较高的。
for (int i = 0; i < 10000; i++)
System.out.println(Thread.currentThread().getName() + "-->" + i);
// 最高优先级:10
// 最低优先级:1
// 默认优先级:5
System.out.println("最高优先级:" + Thread.MAX_PRIORITY);
System.out.println("最低优先级:" + Thread.MIN_PRIORITY);
System.out.println("默认优先级:" + Thread.NORM_PRIORITY);
调用yield暂停当前线程
package com.yyl.threadTest;
class MyThread extends Thread
@Override
public void run()
for(int i = 1; i <= 10000; i++)
//每100个让位一次。
if(i % 100 == 0)
Thread.yield(); // 当前线程暂停一下,让给主线程
System.out.println(Thread.currentThread().getName() + "--->" + i);
public class ThreadScheduling
public static void main(String[] args)
Thread t = new Thread(new MyThread());
t.setName("t");
t.start();
for(int i = 1; i <= 10000; i++)
System.out.println(Thread.currentThread().getName() + "--->" + i);
以上是关于JAVA抢占式线程调度的问题的主要内容,如果未能解决你的问题,请参考以下文章