yield()方法让当前线程暂停后,只有优先级>=当前线程的处于就绪状态的线程才能获取CPU执行权限。
yield()方法重载
public static native void yield();:静态方法。
yield()示例
//让当前线程暂停
Thread.yield();
线程优先级
每个线程执行都有一定的优先级,优先级高的线程获得CPU执行权限的机会比较大。
每个线程默认的优先级与创建它的父线程的优先级相同。所以main线程的优先级一般和自己创建的子线程优先级一样。
Thread类提供setPriority(int newPriority)和getPriority()方法设置和返回指定线程的优先级。其中setPriority()方法的参数可以是一个整数(1-10之间),也可以是静态常量。
MAX_PRIORITY:值为10.
MIN_PRIORITY:值为1.
NORM_PRIORITY:值为5.
join()方法
join()方法介绍
Thread类提供join()方法让一个线程等待另一个线程完成的方法;就是将指定的线程加入到当前线程,这样两个交替执行的线程就变成了顺序执行的线程,如线程A调用了线程B的join()方法,则线程A会等待线程B执行完毕后才会继续执行自己。
join()方法由使用线程的程序调用,调用线程调用线程t的t.join()方法后将会被阻塞,直到线程t执行完毕,调用线程才能继续执行。一般就是用于主线程内,等待其他线程执行完毕后,再继续执行main()函数。
join()方法重载方式
public final void join() throws InterruptedException:等待被join的线程执行完毕。
public final synchronized void join(long millis) throws InterruptedException:等待被join的线程的超时时间为millis毫秒。如果在millis毫秒内被join的线程还未结束执行流程,则调用线程不再等待。
public final synchronized void join(long millis, int nanos) throws InterruptedException:等待被join的线程的时间最长为millis毫秒+nanos毫微秒。(很少用)
join()方法示例
(1)未使用join()方法
代码
public class JoinMethodTest {
public static void main(String[] args) {
System.out.println(“main thread start”);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(“child thread start”);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(“child thread finshed”);
}
});
thread.start();
System.out.println(“main thread finshed”);
}
}
运行结果
main thread start
main thread finshed
child thread start
child thread finshed
可以从运行结果看出,main()主线程日志打印的很快,没有等待子线程打印就结束了。
(2)使用join()方法
代码
public class JoinMethodTest {
public static void main(String[] args) {
System.out.println(“main thread start”);
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
System.out.println(“child thread start”);
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(“child thread finshed”);
}
});
thread.start();
//加入join()方法等待子线程执行完毕,才执行主线程。
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(“main thread finshed”);
}
}
运行结果
main thread start
child thread start
child thread finshed
main thread finshed
从运行结果可以看出,main thread finshed结果是在最后打印的,加入join()方法等待子线程执行完毕,才执行主线程。
6种状态的线程生命周期解释
Q&A
为何启动线程需要用start()方法而不是直接调用run()方法?
调用start()方法启动线程,系统会将该线程对象的run()方法当作线程执行体来处理。
直接调用线程对象的run()方法,该方法会被立即执行,而在run()方法返回之前其他线程无法并发执行(系统会将线程对象的当作一个普通对象,将run()方法当作一个普通方法,而不是线程执行体。)
start()方法和run()方法
java Thread中,run方法和start()方法的区别
概念:start()是启动线程,让线程从新建状态变为就绪状态;线程得到CPU时间片后,执行run()中的线程执行体;
调用次数:start()只能调用一次;run()可以重复调用。
方法类型:启动线程只能用start(),系统会把run()方法当做线程执行体处理;如果直接调用run(),系统会把线程对象当作普通对象,此时run()也是一个普通方法,而不是线程执行体。run()方法只是类的一个普通方法而已,如果直接调用run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码。。
源码:start()源码中实际上通过本地方法start0()启动线程,会新运行一个线程,新线程会调用run()方法;而run()源码中target是Runnable对象,run()直接调用Thread线程的Runnable成员的run()方法,并不会新建一个线程。
多线程:用 start方法来启动线程,是真正实现了多线程, 通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法。但要注意的是,此时无需等待run()方法执行完毕,即可继续执行下面的代码。所以run()方法并没有实现多线程。
sleep()和yield()方法的区别
依赖线程优先级:sleep()方法暂停当前线程后,会给其他线程执行机会,而不在乎其他线程的优先级;
yield()方法暂停当前线程后,只会给优先级相同或更高的线程执行机会。
线程转入状态:sleep()方法将线程转入阻塞状态,知道经过阻塞时间才会转入就绪状态;
yield()方法不会将线程转入阻塞状态,而是将线程转入就绪状态。
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
总结
本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!
MySQL50道高频面试题整理:
果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)**
[外链图片转存中…(img-fNGPhypK-1710969451635)]
总结
本文从基础到高级再到实战,由浅入深,把MySQL讲的清清楚楚,明明白白,这应该是我目前为止看到过最好的有关MySQL的学习笔记了,我相信如果你把这份笔记认真看完后,无论是工作中碰到的问题还是被面试官问到的问题都能迎刃而解!
MySQL50道高频面试题整理:
[外链图片转存中…(img-UHMRsphw-1710969451635)]