Java 线程的调度


线程的调度

  • 线程的调度分为分时调度和抢占式调度:
  • 分时调度:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间;
  • 抢占式调度:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java 使用的为抢占式调度

1. 线程栈

  • 线程栈:某时刻内内存中线程调度的栈信息,当前调用的方法总是位于栈顶,线程栈的内容是随程序的运行动态变化的,所以线程栈必须选择一个运行的时刻(即代码运行到什么地方);
  • 线程(调用)栈的变化过程:

线程栈


2. 线程的优先级

  • Java 线程有10个优先级,用数字1~10表示,线程默认的优先级是5级;
  • 可以通过 setPriority(int) 方法设置优先级,通过 getPriority() 方法获知一个线程的优先级;
  • 有3个常数用于表示线程的优先级:Thread.MIN_PRIORITY Thread.MAX_PRIORITY Thread.NORM_PRIORITY,对应优先级分别为 1/10/5;

3. 线程休眠

  • sleep(long millis) 方法用于线程的休眠;
public class Test extends Thread {
    public void run() {
        loop();
    }

    public void loop() {
        String name = Thread.currentThread().getName();
        System.out.println(name + " ---->> 刚进入loop()方法");
        for (int i = 0; i < 3; i++) {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException x) {
            }
            System.out.println("name=" + name);
        }
        System.out.println(name + " ---->> 离开loop()方法");
    }

    public static void main(String[] args) {
        Test t = new Test();
        t.start();
        try {
            Thread.sleep(700);
        } catch (InterruptedException x) {
        }
        t.loop();
    }
}
/*
输出
Thread-0 ---->> 刚进入loop()方法
main ---->> 刚进入loop()方法
name=Thread-0
name=main
name=Thread-0
name=main
name=Thread-0
Thread-0 ---->> 离开loop()方法
name=main
main ---->> 离开loop()方法
 */

4. 线程让步

  • 线程让步:指暂停当前正在执行的线程对象,转而执行其他线程;
  • 如果当前运行的线程优先级大于或等于线程池中其他线程的优先级,当前线程能获得更多的执行时间;如果当前运行的线程想让和它相同优先级的其他线程获得运行机会,使用让步方法 yield() 即可;
  • yield() 方法只是让当前线程从运行状态转到可运行状态;
public class Test {
    public static void main(String[] args) {
        Thread t1 = new MyThread1();
        Thread t2 = new Thread(new MyRunnable1());
        t2.start();
        t1.start();
    }
}

class MyThread1 extends Thread {
    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println("线程1 第" + i + "次执行!");
        }
    }
}

class MyRunnable1 implements Runnable {
    public void run() {
        for (int i = 1; i <= 3; i++) {
            System.out.println("线程2 第" + i + "次执行!");
            Thread.yield();
        }
        for (int i = 1; i <= 10000; i++) ;
    }
}
/*
输出
线程2 第1次执行!
线程1 第1次执行!
线程2 第2次执行!
线程1 第2次执行!
线程2 第3次执行!
线程1 第3次执行!
 */

5. 线程联合

  • join() 方法让一个线程 A 与另一个线程 B 联合,即 A 加到 B 的尾部,自 A 执行完毕前不能执行 B,A 执行完毕,B 才能重新转为可运行状态;
public class Test {
    public static void main(String args[]) throws Exception {
        Thread sub = new Sub();
        sub.setName("子线程");
        System.out.println("主线程main 开始执行。");
        sub.start();
        System.out.println("主线程main 等待线程sub 执行……");
        sub.join();
        System.out.println("主线程main 结束执行。");
    }
}

class Sub extends Thread {
    public void run() {
        System.out.println(this.getName() + "开始执行。");
        System.out.println(this.getName() + "正在执行……");
        try {
            sleep(3000);
        } catch (InterruptedException e) {
            System.out.println("interrupted!");
        }
        System.out.println(this.getName() + "结束执行。");
    }
}
/*
输出
主线程main 开始执行。
主线程main 等待线程sub 执行……
子线程开始执行。
子线程正在执行……
 */
发布了185 篇原创文章 · 获赞 181 · 访问量 5350

猜你喜欢

转载自blog.csdn.net/Regino/article/details/104693578
今日推荐