Java 线程调度
一、什么是线程调度
1.当同一时刻有多个线程处于可运行状态,它们需要排队等待CPU资源,每个线程会自动获得一个线程的优先级(Priority),优先级的高低反映线程的重要或紧急程度。
2.可运行的线程按优先级排队,线程调度依据建立在优先级基础上的“先到先服务”原则。
3.线程调度管理器负责线程排队和在线程间分配CPU,并按线程调度算法进行调度。当线程调度管理器选中某个线程时,该线程获得CPU资源进入运行状态。
4.Java线程调度是抢占式调度,即在当前线程执行过程中如果有一个更高优先级的线程进入可运行状态,则这个更高优先级的线程立即被调度执行。
二、常用的调度方法
1.join()
调用该方法的线程强行进入运行状态,将上个线程阻塞。
public class TestJoin {
public static void main(String[] args) {
//使用匿名内部类的方式 创建线程A
Thread thread = new Thread(new Runnable() {
//重写方法
@Override
public void run() {
//使用匿名内部类创建线程B
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("线程B");
}
});
//调用线程B开始执行
thread1.start();
//循环五次,第二次时强行执行线程B
for (int i = 1; i <= 5; i++) {
if (i==2){
try {
//强行执行
thread1.join();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println("线程A");
}
}
});
//调用start()方法开始线程
thread.start();
}
}
运行结果:
2.sleep(long millis)
调用该方法的线程进入睡眠,期间释放CPU资源
public class Wait {
//线程休眠
public static void sleep(int second){
for (int i = 1; i <= second; i++) {
System.out.println("线程休眠" + i + "秒");
try {
// 静态方法sleep() 可直接调用
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
测试类:
public class Test {
public static void main(String[] args) {
System.out.println("main()开始");
Wait.sleep(5);
System.out.println("main()结束");
}
}
运行结果:
3.yield()
调用该方法的线程会礼让,但不意味着睡眠,线程让出资源后,自己会再次抢占。
package com.yield;
public class TestYield {
public static void main(String[] args) {
//创建线程程 使用匿名内部类
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
for (int i = 1; i <= 5; i++) {
//当循环第二次的时候 将此次线程礼让出去 供其他进程抢占CPU资源
//但自己也会进行抢占
if (i == 2) {
System.out.print("礼让:");
Thread.yield();
}
System.out.println("线程A");
}
}
});
//创建线程 使用匿名内部类->lambda表达式
Thread thread2 = new Thread(() -> System.out.println("线程B"));
//执行两个线程程
thread1.start();
thread2.start();
}
}
运行结果:
4.setDaemon()
守护线程,即该线程会随着其他线程结束而慢慢结束
package com.setdaemon;
public class Test {
public static void main(String[] args) {
// 被设置成守护线程后 该线程随着其他线程停止自己也慢慢停止
// 创建线程任务
MyRun myRun = new MyRun(); // 女神循环5次结束
MyRun01 myRun01 = new MyRun01();// 备胎循环100次结束
// 创建 线程
Thread thread1 = new Thread(myRun,"女神");
Thread thread2 = new Thread(myRun01,"备胎");
// 设置守护线程 备胎不一定循环100次
// 而是随着女神线程的结束自己慢慢结束
thread2.setDaemon(true);
// 启动线程
thread1.start();
thread2.start();
}
}
运行结果: