浅说多线程(中)

三、怎么停止和中断线程

停止线程的三种情况:

1.run运行结束
2.异常退出
3.stop()强制中止,这个不推荐使用,存在风险,可能就会产生数据不一致问题。

中断线程:

线程中断就是让目标线程停止执行,但它不会使线程立即终止,而是给线程发送一个通知,告诉线程jvm希望你退出执行,至于目标线程何时退出,则完全由它自己决定(如果立即停止,会造成与stop一样的问题)。

JDK中线程中断相关的三个方法:

//线程中断
public void interrupt(){}
//判断线程是否中断
public boolean isInterrupted() {}
//判断线程是否中断,并清除当前中断状态
public static boolean interrupted(){}

四、线程的生命周期
和人的生老病死一样,在线程的生命周期中,它也会经历很多状态,下面这张图就说明了一个线程的“一生”

image.png

  1. 创建状态,当程序使用new关键字创建了一个线程之后,该线程就处于新建状态,此时仅由JVM为其分配内存,并初始化其成员变量的值
  2. 就绪状态,当线程对象调用了start()方法之后,该线程处于就绪状态。Java虚拟机会为其创建方法调用栈和程序计数器,等待调度运行
  3. 运行状态,如果处于就绪状态的线程获得了CPU,开始执行run()方法的线程执行体,则该线程处于运行状态
  4. 阻塞状态,当处于运行状态的线程失去所占用资源之后,便进入阻塞状态,比如调用sleep()方法,是自己进入阻塞状态
  5. 在线程的生命周期当中,线程的各种状态的转换过程

五、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方法的使用

上一篇

下一篇

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文主要讲了java中多线程的使用方法、线程同步、线程数据传递、线程状态及相应的一些线程函数用法、概述等。 首先讲...
    李欣阳阅读 2,492评论 1 15
  • Java多线程学习 [-] 一扩展javalangThread类 二实现javalangRunnable接口 三T...
    影驰阅读 2,986评论 1 18
  • 林炳文Evankaka原创作品。转载自http://blog.csdn.net/evankaka 本文主要讲了ja...
    ccq_inori阅读 668评论 0 4
  • 一扩展javalangThread类二实现javalangRunnable接口三Thread和Runnable的区...
    和帅_db6a阅读 497评论 0 1
  • 此片文章主要总结的是Thread类及相关的基础概念和API,首先需要厘清线程调度中的几个基本概念: 一、线程调度的...
    千淘萬漉阅读 2,613评论 0 2