Java线程的控制详解
1. join线程:
在线程执行过程中,有时想让另一个线程先执行,比如将一大问题分割成许多小问题,给每一个小问题分配线程,但所有小问题处理完后再让主线程进一步操作。此时我们可以在主线程中调用其它线程的join()方法,以阻塞调用线程(在这里为主线程)。
示例代码:
package org.frzh.thread;
public class JoinThread extends Thread{
//提供一个有参构造器,用来设置线程的名字
public JoinThread(String name) {
super(name);
}
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + " " + i);
}
}
public static void main(String[] args) {
//启动子线程
new JoinThread("新线程").start();
for (int i = 0; i < 100; i++) {
if (i == 20) {
JoinThread jt = new JoinThread("被join的线程");
jt.start();
//main线程调用了jt线程的join方法,则main线程必须等待jt执行完之后才能执行
try {
jt.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(Thread.currentThread().getName() + " " +i);
}
}
}
本来有三套线程(两条子线程和一main线程),当i=20后,main线程被阻塞必须等到“被join线程”执行完之后才有机会执行,所以此后只有两条线程执行。
join()方法的三种重载形式:
join():等待被join线程执行完;
join(long millis):等待被join线程执行最长为mills豪秒,在这之后即使被join线程没有执行完也不再等待;
join(long millis, int nanos):等待被join线程执行最长时间为millis毫秒+nanos微秒。(此方法基本用不上)。
2:后台线程:
有一种线程,他是在后台运行,他的任务是为其他线程服务,这种线程被称为“后台线程”、“守护线程”或“精灵线程”。当所有前台线程都死亡后,后台线程会自动死亡。
示例代码:
package org.frzh.thread;
public class DaemonThread extends Thread{
public void run() {
for (int i = 0; i < 1000; i++) {
System.out.println(getName() + " " +i);
}
}
public static void main(String[] args) {
DaemonThread dt = new DaemonThread();
//将此线程设置为后台线程
dt.setDaemon(true);
dt.start();
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
//前台线程结束,那么后台线程dt也会结束,所以它执行不到999
}
}
主线程默认是前台线程,前台线程创建的子线程默认是前台线程,后台线程创建的子线程默认是后台线程。
3.线程睡眠(sleep):
前面的join方法是让调用线程等待被join线程执行完之后再继续执行,而sleep()方法是让调用线程阻塞一段时间后再重新进入就绪状态等待被调度。因此它通常用来暂停程序的执行。
示例代码:
package org.frzh.thread;
import java.util.Date;
public class SleepThread{
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
System.out.println("当前时间:" + new Date());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
sleep()方法的两种重载方式:
static void sleep(long millis):让当前线程暂停millis毫秒,并进入阻塞状态。该方法会受到系统计时器和线程调度器的精度和准度的影响。
static void sleep(long millis, int nanos):暂停mills毫秒+nanos微秒,并进入阻塞状态,同样会受系统计时器和线程调度器的精度和准度的影响。基本不用。
4.线程让步(yield):
yield()方法和sleep方法有点类似,它同样可以使当前正在运行的线程暂停,但他不会阻塞该线程,只是将他转入就绪状态(注意不是阻塞状态)。yield()方法只会让和它同等优先级或更高优先级的线程有被执行的机会,所以某一线程调用该方法后可能又被重新调度回来继续执行。
示例代码:
package org.frzh.thread;
public class YieldThread extends Thread{
public YieldThread() {
}
public YieldThread(String name) {
super(name);
}
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(getName() + " " +i);
if (i == 20) {
//当前线程让步
Thread.yield();
}
}
}
public static void main(String[] args) {
//启动两条并发线程
YieldThread yt1 = new YieldThread("高级");
//设置yt1为最高优先级
yt1.setPriority(Thread.MAX_PRIORITY);
yt1.start();
YieldThread yt2 = new YieldThread("低级");
yt2.setPriority(Thread.MIN_PRIORITY);
yt2.start();
/*
* 如果不给线程设置优先级,则两个线程的优先级是相同的,所以两线程会交替执行,当调用yield后会让另一个线程执行;
* 但是,给两个线程分别设置上述优先级之后,刚开始高级线程执行,当i=20时,调用yield,但由于yield方法只会
* 给和它同优先级或更高优先级的线程执行机会,所以此时仍是高级线程执行,而不会让给低级线程
*/
}
}
5:改变线程的优先级:
此举比较简单,只需调用调用实例方法setPriority(int priority)方法即可。每个线程默认与其父线程的优先级相同,main线程默认具有普通优先级(5)。java提供1~10个优先级,也可以使用三个静态常量:
MAX_PRIORITY:10
MIN_PRIORITY:1
NORM_PRIORITY:5
注意的是:尽管java提供10个优先级,但是不同的系统支持的优先级不一样,所以尽量避免直接使用1~10之间的数字,而使用静态常量,以保证具有良好的可移植性。
相关文章
springcloud gateway如何实现路由和负载均衡
这篇文章主要介绍了springcloud gateway如何实现路由和负载均衡的操作,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-07-07
SpringBoot高级配置之临时属性、配置文件、日志、多环境配置详解
这篇文章主要介绍了SpringBoot高级配置之临时属性、配置文件、日志、多环境配置,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2023-02-02
Nacos服务实例的权重设置方式(以及设置为0时的作用与场景)
这篇文章主要介绍了Nacos服务实例的权重设置方式(以及设置为0时的作用与场景),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-07-07
Java后端对接微信支付(小程序、APP、PC端扫码)包含查单退款
微信支付我们主要聚焦于这三种支付方式,其中JSPAI与APP主要与uniapp开发微信小程序与APP对接,本文主要介绍了Java后端对接微信支付(小程序、APP、PC端扫码)包含查单退款,具有一定的参考价值,感兴趣的可以了解一下2021-12-12
SpringBoot2零基础到精通之异常处理与web原生组件注入
SpringBoot是Spring全家桶的成员之一,基于约定优于配置的思想(即有约定默认值,在不配置的情况下会使用默认值,在配置文件下配置的话会使用配置的值)。SpringBoot是一种整合Spring技术栈的方式(或者说是框架),同时也是简化Spring的一种快速开发的脚手架2022-03-03
SpringCloud使用AOP统一处理Web请求日志实现步骤
这篇文章主要为大家介绍了SpringCloud使用AOP统一处理Web请求日志实现步骤,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪2023-08-08
springboot后端配置多个数据源、Mysql数据库的便捷方法
实现springboot 后端配置多个数据源、Mysql数据库,只需要新建 Mapper、实体类 相应的文件夹,将不同数据源的文件保存到对应的文件夹下,添加绑定数据库配置Config,就可以轻松完成2021-08-08


最新评论