1. 创建线程的方式有几种
  2. 三种方式的优缺点是什么
  3. 线程有哪些状态
  4. 线程的生命周期生是怎样的
  5. 如何启动一个线程
  6. start和run方法有什么区别
  7. 如何终止一个正在运行的线程
  8. 什么叫线程安全
  9. 线程和进程有什么区别
  10. 线程之间是怎么通信的
  11. 线程中的yield()方法有什么作用
  12. yield()方法与sleep()方法的区别

1.创建线程有几种方式?

  • 继承Thread
  • 实现Runnable
  • 实现Callable

2.三种方式的优缺点是什么

  • 对于继承Thread方式,优点是操作简单,缺点很致命,因为java只支持单继承,如果使用这种方式,就无法继承其他类,不灵活不推荐使用
  • 对于实现Runnable接口,刚好解决了Thread单继承问题,可以实现多个接口。但是也有缺点就是拿不到线程的返回值。
  • 对于实现Callable接口,解决前面两个的问题,但是编码复杂,增加使用难度

3.线程有哪些状态

源码里面可以看 java.lang.Thread 类里面,去看看,Thread类中有个内部类:State。这个就是线程的状态。

总共有6种状态:

  • (NEW)初始状态
  • (RUNNABLE)运行状态
  • (BLOCKED)阻塞状态
  • (WAITINGN)等待状态
  • (TIMED_WAITING)超时等待状态
  • (TERMINATED)终止状态

4.线程的生命周期是怎样的

  1. newThread表示NEW状态
  2. 调用start方法来到(RUNNABLE)状态
  3. 等待synchronize方法或模块的时候到(BLOCKED)阻塞状态。获取锁后又来到(RUNNABLE)状态
  4. 调用Object的wait方法、Thread的join方法、LockSupport.park()方法来到(WAITING)等待状态。反之,调用Object.notify、Object.notifyAll、LockSupport.unpark(Thread)方法状态又回到(RUNNABLE)状态
  5. 调用Thread的sleep(long)方法、Object的wait(long)方法、Thread的join(long)方法、LockSupport的parkNnos()方法、LockSupport的parkUnit方法来到(TIMED_WAITING)超时等待状态。反之,调用Object的notify方法、Object的notifyAll方法、LockSupport的unpark ( Thread )方法状态又回到(RUNNABLE)状态
  6. 线程执行完成后来到(TERMINATED)终止状态。

    并发编程12道面试题 - 图1

5.如何启动一个线程

调用线程的start方法就可以启动一个线程

6.start方法和run方法有什么区别

启动线程是start方法不是run方法。如果直接调用run方法就和调用一个普通实例一样,不是创建一个线程,只是方法的调用,在程序中只有主线程这一个线程,没有达到启动线程的目的。

7.怎么终止正在运行中的线程

常见的三种方式:

  • 调用stop方法,使用stop方法强行终止,但是这种方式一般不建议使用,和强行关机一样,一些还没执行完的任务也会被终结
  • 使用interrupt方法中断线程
  • 使用退出标识吗,使线程正常退出

8.什么叫做线程安全

代码在多线程和单线程下执行,永远都获得一样的结果,这样的代码就是线程安全的。

9.线程和进程有什么区别

  • 从概念上来说,进程是一个“执行中的程序”,是系统进行资源分配的调度的独立单位;线程是操作系统能都进行运算调度的最小单位,它是被包含在进程之中的,是进程中的实际运行单位。
  • 从CPU层面来说,进程和线程都是CPU工作时间段的描述,只不过颗粒程度大小不一样
  • 从地址空间来说,同一进程的线程共享本进程的地址空间,而进程之间则是独立的地址空间

10.线程之间是如何通信的

一般有两种方式

  • 内存共享,在共享内存的并发模型里,线程之间共享程序的公共状态,线程之间通过读-写内存中的公共状态隐式进行通信
  • 消息传递,通过明确的发送消息来显式通信,会涉及到等待唤醒机制 wait()和notify()等问题

11.线程中的yield()有什么作用

在多线程里面,yield()方法就是线程让步的意思。当一个线程使用这个方法之后,他会把自己的CPU执行时间让掉,让自己或者其他的的线程运行。

12.yield()方法与sleep()方法的区别?

  • 从线程优先级来说,yield()方法只会给同等优先级或者更高优先级的线程运行机会,但是,sleep()方法给其他方法时候不考虑线程的优先级。
  • 从运行后的状态来说,运行yield()方法后,当前线程会重新回到可执行的状态,有可能执行后没有其他线程又会自己重新执行。但是sleep()方法后,线程会进入到阻塞状态,所以短时间sleep()方法的线程是不会执行的
  • 从抛出异常方面来说,yield()方法没有声明任何异常,而sleep()方法会抛出InterruptdException
  • 从可移植性来说,sleep()方法比yield()方法具有更好的移值性