上一篇:教你随心操控线程状态 | 带你学《Java语言高级特性》之七
【本节目标】
通过阅读本节内容,你将学会使用join方法让线程强制一直执行、使用yield方法礼让其他线程优先执行,了解并学会设置线程的优先级使系统自动调度资源执行线程。
线程的强制执行
所谓的线程的强制执行指的是当满足于某些条件之后,某一个线程对象将可以一直独占资源,一直到该线程的程序执行结束。
范例:观察一个没有强制执行的程序
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(() -> {
for (int x = 0; x < 100; x++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "执行、x = " + x);
}
}, "玩耍的线程");
thread.start();
for (int x = 0; x < 100; x++) {
Thread.sleep(100);
System.out.println("【霸道的main线程】number = " + x);
}
}
}
图一 没有强制执行的程序
这个时候主线程和子线程都在交替执行着,但是如果说现在希望主线程独占执行,那么就可以用Thread类中的方法:
强制执行 :public final void join(long millis) throws InterruptedException;
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Thread mainThread = Thread.currentThread(); //获得主线程
Thread thread = new Thread(() -> {
for (int x = 0; x < 100; x++) {
if (x == 3) { //现在霸道的线程来了
try {
mainThread.join(); //霸道的线程要先执行
} catch (Exception e) {
e.printStackTrace();
}
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "执行、x = " + x);
}
}, "玩耍的线程");
thread.start();
for (int x = 0; x < 100; x++) {
Thread.sleep(100);
System.out.println("【霸道的main线程】number = " + x);
}
}
}
图二 强制执行
在进行线程强制执行的时候,一定要获取强制执行线程对象之后才可以执行join()的调用。
线程礼让
线程的礼让指的是先将资源让出去让别的线程先执行。线程的礼让可以使用Thread类中提供的方法:
public static void yield();
范例:使用礼让操作
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Thread thread = new Thread(() -> {
for (int x = 0; x < 100; x++) {
if(x%3==0){
Thread.yield(); //线程礼让
System.out.println("### 玩耍的线程礼让执行 ###");
}
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "执行、x = " + x);
}
}, "玩耍的线程");
thread.start();
for (int x = 0; x < 100; x++) {
Thread.sleep(100);
System.out.println("【霸道的main线程】number = " + x);
}
}
}
图三 礼让线程
礼让执行的时候每一次调用yield()方法都只会礼让一次当前的资源。
线程优先级
从理论上来讲,线程的优先级越高,越有可能先执行(越有可能先抢占到资源)。在Thread类中针对优先级的操作提供有如下两个处理方法:
设置优先级:public final void setPriority(int newPriority);
获取优先级:public final int getPriority();
在进行优先级定义的时候都是通过int型的数字来完成的,而对于此数字的选择在Thread类中就定义了三个常量:
最高优先级:public static final int MAX_PRIORITY 、10;
中等优先级:public static final int NORM_PRIORITY 、5;
最低优先级:public static final int MIN_PRIORITY 、1;
范例:观察优先级
public class ThreadDemo {
public static void main(String[] args) throws Exception {
Runnable run = () -> {
for (int x = 0; x < 10; x++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "执行。");
}
};
Thread threadA = new Thread(run, "线程对象A");
Thread threadB = new Thread(run, "线程对象B");
Thread threadC = new Thread(run, "线程对象C");
threadA.setPriority(Thread.MIN_PRIORITY);
threadB.setPriority(Thread.MIN_PRIORITY);
threadC.setPriority(Thread.MAX_PRIORITY);
threadA.start();
threadB.start();
threadC.start();
}
}
图四 线程优先级执行
主方法是一个主线程,那么主线程的优先级呢?默认线程对象的优先级呢?
public class ThreadDemo {
public static void main(String[] args) throws Exception {
System.out.println(Thread.currentThread().getPriority()); //5
System.out.println(new Thread().currentThread().getPriority()); //5
}
}
主线程属于中等优先级,而默认创建的线程也是中等优先级。
想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学