抢占调度模型
-
概述:优先让优先级高的线程使用 CPU ,如果线程的优先级相同,那么随机会选择一个,优先级高的线程获取的 CPU 时间片相对多一些
-
Thread 类中一些关于线程的方法
方法 简述 public final int getPriority() 返回此线程的优先级 public final void setPriority(int newPriority) 设置此线程的优先级 -
线程的优先级
- 范围:从 1~10,线程默认优先级:5
- 线程优先级高,仅仅表示线程获取CPU的时间片的几率高,但是要在次数比较多,或者多次运行的时候才能看到你想要的效果
class MyThread extends Thread{ private int val; public MyThread(int val){ this.val = val; } @Override public void run() { System.out.println(val); } } public class Test1 { public static void main(String[] args) { // 创建线程对象 MyThread m1 = new MyThread(1); MyThread m2 = new MyThread(2); MyThread m3 = new MyThread(3); MyThread m4 = new MyThread(4); // 展示线程对象的优先级 System.out.println("m1:" + m1.getPriority() + "\nm2:" + m2.getPriority() + "\nm3:" + m3.getPriority() + "\nm4:" + m4.getPriority()); // 设置优先级 m1.setPriority(10); m2.setPriority(8); m3.setPriority(6); m4.setPriority(4); // 启动线程,查看结果 m1.start(); m2.start(); m3.start(); m4.start(); } }
注意:按照我们设置的优先级,m1 线程 抢到的几率是最高的,依次向下,但是,一定输出 1 2 3 4吗,不一定的,我们只是说,抢占的几率。
线程声明周期
-
概述:线程的生命周期分为 4 个
- 新建 (创建线程对象)
- 就绪 (有执行资格,没有执行权)【举个简单的例子:商家有了营业资格证,但是他一定能在有证的那一刻营业吗】
- 运行 (有执行资格,有执行权)
- 死亡 (线程死亡,变成垃圾)
-
声明周期图
如果上述还未理解,我们结合这个例子看下:有个大型演唱会,邀请了很多明星(可理解为创建了对象),但是舞台呢,在某一时刻只允许一位明星表演,那在后边等待的人(有资格表演,但是现在没有权力登台),接着轮到这个明星(此时他既有资格,又有权力),如果顺利演唱结束(那就没他啥事了),但是如果突然他被爆料,那停止他的资格和执行权,直到查清后,他重新拥有资格,等待表演。
线程的一些控制方法
方法 | 简述 |
---|---|
static void sleep(long millis) | 使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性 |
void join() | 等待这个线程死亡。 |
public final void setDaemon(boolean on) | 如果 true ,将此线程标记为守护线程 将此线程标记为daemon线程或用户线程。 当运行的唯一线程都是守护进程线程时,Java虚拟机将退出。 线程启动前必须调用此方法。 |
案例一:让线程睡一会
public class Test2 {
public static void main(String[] args) throws InterruptedException {
printSlowly("你好,中国!欢迎来到编程世界!....",300);
}
public static void printSlowly(String text , long time) throws InterruptedException {
// 字符串转换成字符数组
for (char ch : text.toCharArray() ) {
// 每打一个字,休息 0.3 秒
Thread.sleep(time);
System.out.print(ch);
}
}
}
运行上述程序,会出现 有趣的现象,大家可以运行看一下!
案例二:执行1秒就停了
import java.util.concurrent.TimeUnit;
public class Test3 {
public static void main(String[] args) throws InterruptedException {
String s = "欢迎来到编程世界,小哼与你一同学习,进步!";
// 输出当前线程的名字
System.out.println("程序开始执行,当前线程名:" + Thread.currentThread().getName());
for (int i = 1; i <= 1 ; i++) {
Thread thread = new Thread(new MyRunnable(s,200),"我的线程==" + i);
// 设置为守护线程
thread.setDaemon(true);
thread.start();
}
// 参数意思:将 5 秒转换成 毫秒
Thread.sleep(TimeUnit.SECONDS.toMillis(1)); // 运行后注释这行再试下
}
static class MyRunnable implements Runnable{
private String text;
private long time;
public MyRunnable(String text , long time){
this.text = text;
this.time = time;
}
@Override
public void run() {
try {
printSlowly(text,time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void printSlowly(String text , long time) throws InterruptedException {
for (char ch : text.toCharArray()) {
Thread.sleep(time);
System.out.print(ch);
}
}
}
注意:我们运行程序,可以发现,设置为守护线程,当前线程只剩守护线程,会直接结束程序