线程基础三问——猫眼真题

2020-09-27 11:27:10 浏览数 (2)

线程基础三问——猫眼真题

线程和进程是项目中常遇到的知识点,面试官对此也是对此类知识点经常考察。其中,线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。今天要说的面试三问是关于线程基础相关的:

  • 线程的三种启动方式
  • 线程run和start的区别
  • 线程的几种状态,相互之间是如何转化的

线程的三种启动方式

1)继承thread类

代码语言:javascript复制
    class MyThread :Thread(){
        override fun run() {
            super.run()
        }
    }

    fun test(){
        var t1=MyThread()
        t1.start()
    }

2)实现runnable接口

代码语言:javascript复制
    class MyRunnable : Runnable {
        override fun run() {

        }
    }

    fun test() {
        var t1 = Thread(MyRunnable(),"test")
        t1.start()
    }

3)实现 Callable 接口

代码语言:javascript复制
    class MyCallThread : Callable<String> {
        override fun call(): String {
            return "i got it"
        }

    }

    fun test() {
        var task = FutureTask(MyCallThread())
        var t1 = Thread(task, "test")
        t1.start()
        try {
            //获取结果
            var result = task.get()
        } catch (e: Exception) {
        }
    }

也有人表示其实是两个方法,因为第三个方法FutureTask也是实现了Runnable的方法,只不过表现方法不一样,然后带返回值。这个大家面试的时候可以都说上,然后说说自己的见解,毕竟要让面试官多多看到你的知识面。

线程run和start的区别

  • start方法,用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体中的代码执行完毕而直接继续执行后续的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里的run()方法 称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
  • run方法,run方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

简单的说就是:调用start方法方可启动线程,而run方法只是thread类中的一个普通方法调用,不会启动新线程,还是在主线程里执行。

线程的几种状态,相互之间是如何转化的

1) 初始状态(New)。新创建了一个线程对象就进入了初始状态,也就是通过上述新建线程的几个方法就能进入该状态。

2) 可运行状态,就绪状态(RUNNABLE)。线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu的使用权。以下几种方式会进入可运行状态:

  • 调用start方法。
  • 拿到对象锁
  • 调用yield方法

3)运行状态(RUNNING)。可运行状态(runnable)的线程获得了cpu 时间片 ,执行程序代码。线程调度程序从可运行池中选择一个线程作为当前线程,就会进入运行状态。

4)阻塞状态(BLOCKED)。线程正在运行的时候,被暂停,通常是为了等待某个时间的发生(比如说某项资源就绪)之后再继续运行。wait,sleep,suspend等方法都可以导致线程阻塞。

5)死亡状态(DEAD)。线程run()、main()方法执行结束,或者因异常退出了run()方法,则该线程结束生命周期。死亡的线程不可再次复生。

0 人点赞