Java多线程面试题

1.进程和线程的区别

程序由指令和数据组成,但这些指令要运行,数据要读写,就必须将指令加载至 CPU中,数据加载至内存。在指令运行过程中还需要用到磁盘、网络等设备。进程就是用来加载指令、管理内存、管理 IO 的。
当一个程序被运行,从磁盘加载这个程序的代码到内存中,这时就开启了一个进程。

什么叫做进程:当一个程序被允许,从磁盘加载到这个程序的代码至内存,这时就开启了一个进程。(比如:打开QQ软件,QQ运行后就是一个进程)
什么叫做线程:线程就是一个指令流,将指令流中的一条条指令以一定顺序交给CPU执行。
进程和线程的区别:

  • 进程是正在运行程序的实例,进程中包含了多个线程,每个线程执行不同的任务。
  • 不同的进程使用不同的内存空间(QQ进程与微信进程使用的内存空间是不同的),当前进程下的所有线程可以共享内存空间。
  • 线程比进程更轻量,线程上下文切换成本一般比进程低(上下文切换指的是一个线程切换到另一个线程)

2.并行和并发的区别

两种情况:单核CPU和多核CPU

1.单核CPU

  • 单核CPU下线程实际还是串行执行的
  • 操作系统中有一个组件叫做任务调度器,将cpu的时间片(windows下时间片最小约为 15 毫秒)分给不同的程序使用,只是由于cpu在线程间(时间片很短)切换的速度非常快,给人的感觉是同时运行的 。
  • 总结为一句话就是: 微观串行,宏观并行
  • 一般会将这种线程轮流使用CPU的做法称为并发(concurrent)

2.多核CPU

每个核(core)都可以调度运行线程,这时候线程可以是并行的。

3.并行和并发有什么区别?

并发(concurrent)是同一时间应对(dealing with)多件事情的能力,(在同一刻时间上,还是只做一件事)

并行(parallel)是同一时间动手做 (doing)多件事情的能力,(同一刻时间内,多核CPU同时做多件事)

4.总结

现在都是多核CPU,在多核CPU下
并发是同一时间应对多件事情的能力,多个线程轮流使用一个或多个CPU
并行是同一时间动手做多件事情的能力,4核CPU同时执行4个线程

3.创建线程的方式有哪些?

  • 继承Thread类
  • 实现Runnable接口
  • 实现Callable接口
  • 线程池创建线程(项目中常用的方式)

1.runnable与callable有什么区别?

  • runnable没有返回值,callable的返回值类型与泛型一样。
  • runnable不能向上抛出异常,只能内部消化,callable可以抛出异常。
  • callable可以用Future、FutureTask获取线程的返回值。

2.线程的run和start有什么区别?

  • run相当于一个普通方法,可以在一个线程中多次执行,而start是开启一个线程,一个线程只能开启一次,多次调用就会抛出异常。
  • run(): 封装了要被线程执行的代码,可以被调用多次。
  • start(): 用来启动线程,通过该线程调用run方法执行run方法中所定义的逻辑代码。start方法只能被调用一次。

4.线程包括哪些状态,状态之间如何变换?

线程的状态可以参考JDK中Thread类中的枚举State。

复制代码
    public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called {@code Object.wait()}
         * on an object is waiting for another thread to call
         * {@code Object.notify()} or {@code Object.notifyAll()} on
         * that object. A thread that has called {@code Thread.join()}
         * is waiting for a specified thread to terminate.
         */
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }

简化:

1.线程的6种状态

  1. 新建(new)。
  2. 可执行(runnable)。
  3. 阻塞(blocked)。
  4. 等待(waiting)。
  5. 时间等待(timed_waiting)。
  6. 终止(terminated)。

2.线程状态之间的变化

1.创建线程对象是新建状态。

2.调用start()方法转变为可执行状态。

3.线程获取到了CPU的执行权,执行结束是终止状态。

4.在可执行状态的过程中,如果没有获取到CPU的执行权,可能会切换其它的状态。

(*).如果没有获取到锁(synchronized或lock)进入阻塞状态,获得锁再切换为可执行状态。

(*).如果线程调用了wait()方法进入等待状态,其它线程调用notify()唤醒后可切换为可执行状态。

(*).如果线程调用了sleep()方法,进入计时等待状态,到时间后可切换为可执行状态。

* 表示没有先后顺序

5.新建T1、T2、T3三个线程,如何保证它们按顺序执行?

可以使用线程中的join方法解决。

相关推荐
介一安全5 分钟前
【Frida Android】基础篇6:Java层Hook基础——创建类实例、方法重载、搜索运行时实例
android·java·网络安全·逆向·安全性测试·frida
xyy202516 分钟前
Spring事务的传播方式
java·数据库·spring
@Kerry~24 分钟前
phpstudy .htaccess 文件内容
java·开发语言·前端
roshy24 分钟前
x86、arm、rsc-v指令集架构,指令集、OS、应用3者的关系
java·arm开发·架构
CRMEB系统商城24 分钟前
CRMEB多商户系统(PHP)v3.3正式发布,同城配送上线[特殊字符]
java·开发语言·小程序·php
iナナ34 分钟前
Java优选算法——位运算
java·数据结构·算法·leetcode
毕设源码-钟学长41 分钟前
【开题答辩全过程】以 濒危动物保护管理系统为例,包含答辩的问题和答案
java·eclipse
sali-tec1 小时前
C# 基于halcon的视觉工作流-章45-网格面划痕
开发语言·算法·计算机视觉·c#
一壶浊酒..1 小时前
python 爬取百度图片
开发语言·python·百度
机器视觉知识推荐、就业指导1 小时前
C语言中的预编译是什么?何时需要预编译?
c语言·开发语言