Java多线程(5)——多线程停止(传智播客毕老师视频讲解)

1、线程停止概述

Thread类中stop方法已经过时; 

如何停止线程?

只有一种,就是让run方法结束;只要控制住循环,就可以让run方法结束,也就是线程结束。

开启多线程运行,运行代码通常为循环结构。

以下为一种简单的让线程停止的代码:

public class StopTest  implements Runnable
{
	private boolean flag=true;
	public void run()
	{
		while(flag)
		{
			//try{Thread.sleep(100);}catch(Exception e){}
			System.out.println("...."+Thread.currentThread().getName());
		}
	}
	public void changeFlag()
	{
		flag=false;
	}
}
public class StopDemo 
{
	public static void main(String[] args) 
	{
		int i=0;
		StopTest t=new StopTest();
		Thread t1=new Thread(t);
		Thread t2=new Thread(t);
		t1.start();
		t2.start();
		while(true)
		{
			//try{Thread.sleep(100);}catch(Exception e){}
			if(i++==60)
			{
				t.changeFlag();
				break;
			}
			System.out.println(Thread.currentThread().getName()+"..."+i);
		}
	}
}

特殊情况:

但是如果碰到wait或者await方法,则会进入冻结状态,此时不会读取到标记,那么线程就不会结束,如下代码

import java.util.concurrent.locks.*;
public class StopTest  implements Runnable
{
	private boolean flag=true;
	private Lock lock=new ReentrantLock(); 
	private Condition c=lock.newCondition();
	public void run()
	{
		while(flag)
		{
			lock.lock();
			//try{c.await();}catch(InterruptedException e){}
			try{Thread.sleep(100);}catch(Exception e){}
			System.out.println("...."+Thread.currentThread().getName());
			lock.unlock();
		}
	}
	public void changeFlag()
	{
		flag=false;
	}
}
2、Interrupt方法
正常唤醒方法有notify、signal方法;

Thread类提供interrupt唤醒方法;

注意:interrupt方法不是正常唤醒,是强制唤醒

代码如下:

import java.util.concurrent.locks.*;
public class StopTest  implements Runnable
{
	private boolean flag=true;
	private Lock lock=new ReentrantLock(); 
	private Condition c=lock.newCondition();
	public void run()
	{
		while(flag)
		{
			lock.lock();
			try{Thread.sleep(1);}        //睡眠冻结,将sleep中的时间通过不断的调整,可以得到不同的结果!
			catch(Exception e){System.out.println(Thread.currentThread().getName()+"....Sleep");}
			try{c.await();}                //等待冻结
			catch(InterruptedException e){System.out.println(Thread.currentThread().getName()+".....Exception");}
			System.out.println("...."+Thread.currentThread().getName());
			lock.unlock();
		}
	}
	public void changeFlag()
	{
		flag=false;
	}
}
public class StopDemo 
{
	public static void main(String[] args) 
	{
		int i=0;
		StopTest t=new StopTest();
		Thread t1=new Thread(t);
		Thread t2=new Thread(t);
		t1.start();
		t2.start();
		while(true)
		{
			try{Thread.sleep(10);}catch(Exception e){}
			if(i++==10)
			{
				t.changeFlag();
				t1.interrupt(); //t1唤醒
				t2.interrupt(); //t2唤醒
				
				break;
			}
			System.out.println(Thread.currentThread().getName()+"..."+i);
		}
		try{Thread.sleep(1);}catch(Exception e){}
		t1.interrupt();         //t1唤醒
		t2.interrupt();         //t2唤醒
		System.out.println("over");
	}
}
其强制唤醒机制是,通过interrupt方法强制唤醒在sleep或者await中冻结的线程,以如下运行结果为例:
2.1、将红色不部分sleep参数设置为1,结果如下:


其过程为,t1、t2线程在执行后,先sleep()1ms,由于main线程sleep()10ms,所以主线程运行至判断i++==10之前,t1、t2线程已经进入await(),然后被interrupt中断,报出异常,然后处理异常,然后继续执行下一句;

2.2、将红色不部分sleep参数设置为10,结果如下:


其过程为:

  1. t1、t2线程在执行后,先sleep()100ms,由于main线程sleep()10ms,所以主线程运行至判断i++==10之前,t1线程已经进入await(),但是t2线程还在sleep();
  2. 主线程将标志位置为false,同时开启两个中断唤醒!
  3. t2的sleep冻结状态然后被interrupt中断,报出异常,然后处理异常,然后继续执行下一句;然后t2又进入await()冻结状态;
  4. t1的await冻结状态被interrupt中断,报出异常,然后处理异常,继续执行下一句,循环判断标志位,t1线程结束;
  5. 主线程中在sleep()1ms后,又产生两个中断唤醒,其中t2的中断将t2唤醒,报出异常,然后异常处理,继续执行下一句,循环判断标志位,t2线程结束。

2.3、将红色不部分sleep参数设置为200,结果如下:


过程如2.2分析,只不过这次两个都是在sleep()冻结状态!






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值