多线程基本知识

多线程面试题

线程基本知识

image-20250813123753471

1.进程与线程的区别?

难2出现3
进程是由指令和数据组成,要运行这些指令,数据读写,就要将指令加载到cpu,数据加载到内存。
当一个程序被运行就是开启了一个进程
一个线程就是一个指令流,将指令流一条一条的交给cpu执行,一个进程可以有多个线程
进程和线程区别:
回答

  • 进程是正在运行的程序的实例,进程中包含了线程,每个线程执行不同的任务
  • 不同的进程之间使用不同的内存空间,当前进程之间可以共享内存空间
  • 线程更加轻量级,线程上下文和切换成本比进程小

2.并行和并发有什么区别

难2出现2

单核cpu

1.在单核cpu下实际上还是串行执行的 先去执行线程1再去执行线程2轮着执行
2.操作系统中有一个组件叫做任务调度器的东西,将cpu的时间片分给不同的程序抵用,由于cpu在线程之间切换快说以人感觉就是一起执行的
3.总结为一句话就是微观串行,宏观并行
4.一般将线程轮流使用的做法叫做并发

多核cpu

每个核心都可以调度线程,这个时候线程就是并行
两个cpu可以同时去执行两个线程
区别

  • 并发是同一时刻应对多件事情的能力
  • 并行是同一时间动手做多件事情的能力

举例子
一个家庭主妇要做饭、打扫、给孩子喂奶、轮流做这事情叫做并发
家庭主妇雇佣了一个保姆,他们一起做这些事情既有并发也有并行
家庭主妇雇佣了三个保姆,一个做饭、一个打扫、一个给孩子喂奶,互不打扰叫做并行
回答
在多核cpu下:
并发是同一时刻应对多件事情的能力,多个线程轮流使用一个或者多个cpu
并行就是同一时间做多件事情的能力,比如4个cpu同时执行4个线程

3.创建线程方式有哪些

难2 出现4

4种创建线程的方式

1.继承Thread类

image-20250813135806381 先继承一个Thread接口 重写方法 然后创建实例对象 调用start方法

2.实现runnable 接口

image-20250813140056625

先实现一个Runnable接口重写run方法 创建对象 调用start方法

3.实现Callable接口

image-20250813140406491
1.继承Callable接口重写call方法可以有泛型 异常 返回值 等等
2.创建接口实例对象 
3.创建一个FutureTark<string>对象将接口实例对象复制给他  
4.然后创建thread对象将futureTark对象赋值给thread对象  
5.调用start方法启动线程   用futureTark对象.get可以获得返回值

4.线程池创建线程

image-20250813141411586

继承thread或者实现runnable创建任务 然后创建线程池对象实例 用线程池对象实例去调用submit方法 将刚刚创建的任务提交 最后关闭线程池
回答
继承Thread类
实现runnable 接口
实现Callable接口
线程池创建线程 回答追问在说区别

runnable和callable有什么区别

回答

  • Runnable接口run方法没有返回值 run的异常只能在内部消化不能继续向上抛出
  • Callable接口有返回值和FutureTack配合get方法获取线程的执行结果,有泛型,可以抛出异常

启动线程可以使用run方法吗 用run和start有什么区别

回答
可以使用但是run方法使用是在主线程去运行相当于去调用一个普通方法 而start方法是开启一个线程去异步的运行,不可以开启多次开启线程,只能被调用一次

4.线程包含哪些状态

难3出现4
参考Thread类中的枚举方法
6种
NEW,RUNNABLE,BLOCKED,WATING,TIMED_WAITNG,TERMINATED

image-20250813144441170
    public enum State {
        /**
         * 尚未启动的线程的线程状态。.
         */
        NEW,
        /**
         * 可运行线程的线程状态。可运行线程中的一个线程
		 * 状态在Java虚拟机中执行,但它可能等待来自操作系统的其他资源
		*如处理机.
         */
        RUNNABLE,
        /**
         * 等待监视器锁的线程的线程状态。
         * 处于阻塞状态的线程正在等待监视器锁
         * 进入同步块/方法或
         * 调用后重新进入同步块/方法
         * {@link Object#wait() Object.wait}。
         */
        BLOCKED,
        /**
          等待线程的线程状态。 线程处于等待状态
         */
        WAITING,
        /**
         *指定等待时间的等待线程状态。线程由于调用其中一个而处于定时等待状态
         */
        TIMED_WAITING,
        /**
        *终止线程的线程状态。
        *线程已经完成执行。
         */
        TERMINATED;
    }
image-20250813144734682

当一个线程新建出来就是新建状态,调用了start()方法之后就变成了可运行状态,可运行状态分成了就绪(抢到cpu执行权利之后变成运行)和运行状态,执行完之后变成死亡状态,之间有可能加锁就是没有执行的权利就进入阻塞状态,还有可能是调用了wait()方法就变成了等待状态等待别人调用notify()方法,还有就是调用了sleep(时间)方法就是变成了即使等待状态,等待时间到

image-20250813145440077

5.新建三个线程怎么保证他们的循序执行

难2出现3
使用线程中的join方法
join()等待线程运行结束 加入冒一个线程 等待那个线程完了之后在调用这个线程
阻塞调用此方法的线程进入即时等待状态
image-20250813150613087

6.notify()和notiftyAll()有什么区别

难2出现3

  • notiftyAll()所有wait()的线程
  • noti唤醒一个调用了wait方法的线程

7.java中的wait()和sleep()有什么不同

难3出现3
wait() wait(时间) 到时间之后可以自动唤醒
共同点:都能让当前线程暂时放弃cpu的使用权,进入阻塞状态
不同点:
1.方法的归属不同

  • sleep属于Thread的静态方法

  • wait(),wait(long)属于object的方法每个对象都默认有

2.醒来的时机不一样

  • 带参数的到时间之后都可以被自动的唤醒

  • wait(),wait(long)还可以被notify唤醒,wait()如果不唤醒就会一直等下去

  • 他们都可被打断唤醒

3.锁特性不同

  • wait()必须配合锁对象使用 先获取锁对象,而sleep不用

  • wait执行完后之后会释放锁对象,其他线程可以调用。sleep方法在锁中执行不会释放对象 一个是放弃cpu使用权其他人可以用一个是啊放弃之后你们也不能用

image-20250813152247133

8.怎么停止一个正在运行的线程

难2出现3
3种方式退出线程
1.新建一个退出标记 正常的退出线程
image-20250813153206917image-20250813153315083
2.使用stop方法强制终止,已经作废(不推荐使用)
3.使用interrupt方法中断线程,

  • 打断阻塞的线程的线程会抛出打断异常
  • 打断正常的线程,可以更具打断状态来标记是否退出线程和第一种差不多
image-20250813154055363

本文基于黑马程序员的面试篇b站

posted @ 2025-08-13 15:47  重生在二本学java  Views(12)  Comments(0)    收藏  举报