三、怎么停止和中断线程
停止线程的三种情况:
1.run运行结束
2.异常退出
3.stop()强制中止,这个不推荐使用,存在风险,可能就会产生数据不一致问题。
中断线程:
线程中断就是让目标线程停止执行,但它不会使线程立即终止,而是给线程发送一个通知,告诉线程jvm希望你退出执行,至于目标线程何时退出,则完全由它自己决定(如果立即停止,会造成与stop一样的问题)。
JDK中线程中断相关的三个方法:
//线程中断
public void interrupt(){}
//判断线程是否中断
public boolean isInterrupted() {}
//判断线程是否中断,并清除当前中断状态
public static boolean interrupted(){}
四、线程的生命周期
和人的生老病死一样,在线程的生命周期中,它也会经历很多状态,下面这张图就说明了一个线程的“一生”
- 创建状态,当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由JVM为其分配内存,并初始化其成员变量的值
- 就绪状态,当线程对象调用了start()方法之后,该线程处于就绪状态。Java虚拟机会为其创建方法调用栈和程序计数器,等待调度运行
- 运行状态,如果处于就绪状态的线程获得了CPU,开始执行run()方法的线程执行体,则该线程处于运行状态
- 阻塞状态,当处于运行状态的线程失去所占用资源之后,便进入阻塞状态,比如调用sleep()方法,是自己进入阻塞状态
- 在线程的生命周期当中,线程的各种状态的转换过程
五、Thread的常用方法说明
1. join()方法
jdk中定义:
public final void join()throws InterruptedException: Waits for this thread to die.
用法:
往线程中添加东西的;join方法可以用于临时加入线程,一个线程在运算过程中,如果满足于条件,我们可以临时加入一个线程,让这个线程运算完,另外一个线程再继续运行。
没用join()例子
/**
* @describe
* @author Li DongWei
*/
public class Test1 {
public static void main(String[] args) throws InterruptedException {
MyThread myThread = new MyThread();
Thread th1 = new Thread(myThread);
th1.start();
//th1.join();
System.out.println("结束");
}
}
class MyThread implements Runnable{
private int i = 10;
@Override
public void run() {
while(i > 0)
{
i--;
System.out.println(i);
}
}
}
结束
9
8
7
6
5
4
3
2
1
0
用join()例子,以上代码,将th1.join()的注释去掉
th1.start();
th1.join();
System.out.println("结束");
9
8
7
6
5
4
3
2
1
0
结束
总结
主线程向下转时,碰到了th1.join(),th1要申请加入到运行中来,就是要CPU执行权。这时候CPU执行权在主线程手里,主线程就把CPU执行权给放开,陷入冻结状态。 活着的只有th1了,只有当th1拿着执行权把这些数据都打印完了,主线程才恢复到运行中来;这就是调用join方法的用法。
2. sleep()、yield()方法
sleep()方法使当前线程进入停滞状态,所以执行sleep()的线程在指定的时间内肯定不会执行, 同时sleep函数不会释放锁资源;sleep可使优先级低的线程得到执行的机会,当然也可以让同优先级和高优先级的线程有执行的机会。
yield()方法暂停当前正在执行的线程对象,并执行其他线程。也就是交出CPU一段时间(其他同样的优先级或者更高优先级的线程可以获取到运行的机会);不会释放锁资源。
这两个的区别在于yield只能是同级,或者高级优先执行,而sleep可以低级,同级都可以有优先执行机会。
3. wait(),notify()方法
这两个方法主要是操作锁标志的,所以只能在synchronized方法或者synchronized block中使用;wait()方法在睡眠的时候会放开锁,给其他的线程使用。wait()有两种方式获得锁:
1.wait(longtimeout),通过设定时间来获得锁,值得注意的是,timeout这个时间到了以后,它不会立即醒来,而是要看那个正在使用这把锁的线程是否结束。
2.通过notify()的方法,通知需要这把锁的wait(),使之唤醒,还有wait 方法也要和sleep方法区别,上面说到sleep方法是不释放锁资源的。
本文部分内容参考:
Java线程的终止与线程中断
Thread中的join sleep yield wait notify方法的使用