join加入线程和中断线程
join方法存在于Thread类中,主要作用是使原本并航执行的线程变为串行执行,代码如下:
package thread;
public class Thread5 implements Runnable {//实现Runnable接口
@Override
public void run() {//重写run方法
for (int i = 0; i < 50; i++) {
System.out.println("我是run线程" + i);
}
}
public static void main(String[] args) {
Thread5 t1 = new Thread5();//创建该类的实例对象
Thread t = new Thread(t1);//创建Thread类的实例对象,并把需要同步执行的线程丢进去
t.start();//启动线程
for (int i = 0; i < 50; i++) {
System.out.println("我是主线程" + i);
if (i == 20) {
try {
t.join();//上面启动线程的时候已经把分支线程丢进了Theard的实例里面,所以这里的T代表的就是主线程,代码含义为当i循环到20的时候,那么分支线程加入进来先执行
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
注意:
- join加入线程也会抛出异常,需要用try catch进行捕获
- join方法无法用于run方法中,这和程序加载顺序有关
中断线程:
interrupt():中断线程,它只是做了一个中断标记,是否中断线程,由线程本身来决定!且如果程序抛出一个interruptedException异常,当抛出此异常的时候,当前线程的中断状态将被清除
interrrupted():测试当前线程是否中断,且该方法也会把当前线程的中断状态清除,如果这个方法被连续调用两次,那么第二次调用会返回false。
public class Thread6 implements Runnable {
@Override
public void run() {
for (int i = 0; i < 50; i++) {//线程体
if (Thread.interrupted()){//第二步,写一个if语句判断该线程是否处于中断状态
break;//如果返回结果是true就退出循环
}
System.out.println(Thread.currentThread().getName()+"--"+i);
try {//sleep方法抛出的异常会使线程清除中断状态
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
Thread.currentThread().interrupt();//第三步在catch处理异常的时候加入interrupt可以中断线程
}
}
}
public static void main(String[] args) {
Thread6 t1 = new Thread6();
Thread t = new Thread(t1);
t.start();
for (int i = 0; i <50 ; i++) {
System.out.println(Thread.currentThread().getName()+"--"+i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(i==20){
t.interrupt();//第一步,当i=20的时候就向线程T发送一个中断标记
}
}
}
}
程序执行过程:
类加载完毕,开始寻找Main方法,找到main方法后程序继续执行
- 新建一个该类的实例对象,新建一个Thread类的实例对象,并把类的实例对象丢进Thread类的实例
- Thread类调用自身的start方法启动多线程,start里面会把重写的run方法也加入同步执行
- 两个线程开始同步执行循环,进入到sleep方法中开始交替休眠执行,当main线程进入if语句,i=20时,会给t线程发送一个中断标记,要求t线程中断执行,t线程进入自身的for循环里面重复执行,当接收到中断标记时,它会进入if语句退出循环,循环结束那么t线程也就结束了
自定义标记中断线程:
以上中断线程的方式过于麻烦,我们也可以自己定义一个标记来中断线程,思路如下:
- 在类里定义一个布尔类型的数据类型,初始值为true
- 在类里面重写构造方法flag为true
- 在main方法设置线程终止时机,如果循环到20次的时候,就把flag的值置为false,程序运行到这个时候因为它的值是false了,所以线程会终止进行
public class Thread7 implements Runnable{
public boolean flag = true;
public Thread7(){
flag = true;
}
public static void main(String[] args) {
Thread7 thread7 = new Thread7();
Thread t1 = new Thread(thread7);
t1.start();
for (int i = 0; i < 50; i++) {
System.out.println(Thread.currentThread().getName()+"--"+i);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (i==20){
thread7.flag = false;
}
}
}
@Override
public void run() {
int i = 0;
while (flag){
System.out.println(Thread.currentThread().getName()+i++);
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!