当前位置: 首页 > news >正文

Java面试_并发编程_线程基础

Java面试_并发编程_线程基础

  • 线程基础
    • 线程和进程的区别(出现频率: 3⭐)
    • 并行和并发的区别(出现频率: 2⭐)
    • 线程的创建(出现频率: 4⭐)
    • 线程的状态(出现频率: 4⭐)
    • 让线程按顺序执行(出现频率: 3⭐)
    • notify()和notifyAll()有什么区别(出现频率: 2⭐)
    • wait方法和sleep方法的区别(出现频率: 3⭐)
    • 停止正在运行的线程(出现频率: 2⭐)
  • 来源
  • Gitee地址

线程基础

线程和进程的区别(出现频率: 3⭐)

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

并行和并发的区别(出现频率: 2⭐)

  • 并发是单个CPU同时执行多个线程
  • 并行是多个CPU同时执行多个线程

在这里插入图片描述

线程的创建(出现频率: 4⭐)

创建线程的方式

  • 继承Thread类
  • 实现runnable接口
  • 实现callable接口
  • 线程池创建线程(项目中使用方式)

runnable和callable有什么区别

  • Runnable接口的run方法没有返回值
  • Callable接口的call方法有返回值, 需要FutureTask获取结果
  • Callable接口的call方法允许抛出异常; 而Runnable接口的run方法的异常只能在内部消化, 不能继续上抛

run()和start()有什么区别

  • start(): 用来启动线程, 通过该线程调用run方法中所定义的逻辑代码. start方法只能被调用一次
  • run(): 正常调用方法, 封装了要被线程执行的代码, 可以被调用多次

线程的状态(出现频率: 4⭐)

线程的状态

  • 新建(new)
  • 可运行(runnable)
  • 阻塞(blocked)
  • 等待(waiting)
  • 时间等待(timed_waiting)
  • 终止(terminated)

线程状态之间的变化

  • 创建线程对象是新建状态
  • 调用了start()方法变为可执行状态
  • 线程获取到了CPU的执行权, 执行结束是终止状态
  • 在可执行状态的过程中, 如果没有获取CPU的执行权, 可能会切换为其他状态
    • 如果没有获取锁(synchronized或lock)进入阻塞状态, 获得锁再切换为可执行状态
    • 如果线程调用了wait()方法进入等待状态, 其他线程调用notify()唤醒后可切换为可执行状态
    • 如果线程调用了sleep()方法, 进入计时等待状态, 到时间后可切换为可执行状态

让线程按顺序执行(出现频率: 3⭐)

使用join()方法

public class JoinTest {public static void main(String[] args) {Thread t1 = new Thread(() -> {System.out.println("t1");});Thread t2 = new Thread(() -> {try {// 当t1线程执行完毕后, 线程继续执行t1.join();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("t2");});Thread t3 = new Thread(() -> {try {// 当t2线程执行完毕后, 线程继续执行t2.join();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println("t3");});t1.start();t2.start();t3.start();}
}

notify()和notifyAll()有什么区别(出现频率: 2⭐)

  • notifyAll(): 唤醒所有wait的线程
  • notify(): 随机唤醒一个wait的线程
public class notifyAndNotifyAllTest {static Object lock = new Object();public static void main(String[] args) throws InterruptedException {Thread t1 = new Thread(() -> {synchronized (lock) {System.out.println(Thread.currentThread().getName() + "...waiting...");try {lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(Thread.currentThread().getName() + "...被唤醒了...");}}, "t1");Thread t2 = new Thread(() -> {synchronized (lock) {System.out.println(Thread.currentThread().getName() + "...waiting...");try {lock.wait();} catch (InterruptedException e) {throw new RuntimeException(e);}System.out.println(Thread.currentThread().getName() + "...被唤醒了...");}}, "t2");t1.start();t2.start();Thread.sleep(2000);synchronized (lock) {// lock.notify(); // 随机唤醒一个wait线程lock.notifyAll(); // 唤醒所有wait的线程}}
}

wait方法和sleep方法的区别(出现频率: 3⭐)

共同点

  • wait(), wait(long)和sleep(long)的效果都是让当前线程暂时放弃CPU的使用权, 进入阻塞状态

不同点

  1. 方法归属不同
    • sleep(long)是Thread的静态方法
    • wait(), wait(long)都是Object的成员方法, 每个对象都有
  2. 醒来时机不同
    • 执行sleep(long)和wait(long)的线程都会在等待相应毫秒后醒来
    • wait(long)和wait()还可以被notify()唤醒, wait()如果不唤醒就一直等待
    • 他们都可以被打断唤醒
  3. 锁特性不同
    • wait方法的调用必须先获取wait对象的锁, 而sleep无此限制
    • wait方法执行后会释放对象锁, 允许其他线程获得该对象锁
    • sleep如果在synchronized代码块中执行, 并不会释放对象锁

停止正在运行的线程(出现频率: 2⭐)

  • 使用退出标志, 是线程正常退出, 也就是当run方法完成后线程终止
    public class InterruptDemo extends Thread{volatile boolean flag = false; // 线程执行的退出标记@Overridepublic void run() {while(!flag){System.out.println("MyThread...run...");try {Thread.sleep(3000);} catch (InterruptedException e) {throw new RuntimeException(e);}}}public static void main(String[] args) throws InterruptedException {// 创建MyThread对象InterruptDemo t1 = new InterruptDemo();t1.start();// 主线程休眠6秒Thread.sleep(6000);// 更改标记为truet1.flag = true;}}
    
  • 使用stop方法强行终止(不推荐, 方法已作废)
  • 使用interrupt方法中断线程
    • 打断阻塞的线程(sleep, wait, join)的线程, 线程会抛出InterruptedException异常
    • 打断正常的线程, 可以根据打断状态来标记是否退出线程
    public class InterruptDemo02 {public static void main(String[] args)      throws InterruptedException {// // 1. 打断阻塞的线程// Thread t1 = new Thread(() -> {//     System.out.println("t1正在运行...     ");//     try {//         Thread.sleep(5000);//     } catch (InterruptedException e) {//         throw new RuntimeException(e);//     }// }, "t1");// t1.start();// Thread.sleep(500);// t1.interrupt();// System.out.println(t1.isInterrupted     ());// 2. 打断阻塞的线程Thread t2 = new Thread(() -> {while(true){Thread current = Thread.     currentThread();boolean interrupted = current.     isInterrupted();if(interrupted){System.out.println("打断状态     : "+interrupted);break;}}}, "t2");t2.start();Thread.sleep(500);t2.interrupt();System.out.println(t2.isInterrupted());}
    }
    

来源

黑马程序员. 新版Java面试专题视频教程
小林coding. 图解系统-进程管理

Gitee地址

https://gitee.com/Y_cen/java-interview

相关文章:

Java面试_并发编程_线程基础

Java面试_并发编程_线程基础 线程基础线程和进程的区别(出现频率: 3⭐)并行和并发的区别(出现频率: 2⭐)线程的创建(出现频率: 4⭐)线程的状态(出现频率: 4⭐)让线程按顺序执行(出现频率: 3⭐)notify()和notifyAll()有什么区别(出现频率: 2⭐)wait方法和sleep方法的区别(出现频…...

基于Java的高校实习管理系统设计与实现(亮点:实习记录、实习打分、实习作业,功能新颖、老师没见过、当场唬住!)

高校实习管理系统 一、前言二、我的优势2.1 自己的网站2.2 自己的小程序(小蔡coding)2.3 有保障的售后2.4 福利 三、开发环境与技术3.1 MySQL数据库3.2 Vue前端技术3.3 Spring Boot框架3.4 微信小程序 四、功能设计4.1 主要功能描述 五、系统主要功能5.1…...

傅里叶变换

傅里叶变换常用于缺陷检测项目,对于一些背景偏暗,对比度不明显的场景,傅里叶变换可以起到提升对比度的效果。傅里叶变换从频域角度来处理,对于一些图像像素尺寸大的图像,算法时间往往时间达到1s以上,对于一…...

Vue Grid Layout -️ 适用Vue.js的栅格布局系统,在vue3+上使用

文章目录 1、官网简介2、在vue3中使用1)、需要导入vue3支持的版本插件2)、在mian.js里引入:3)、在组件中使用 3、layout布局的计算逻辑4、 gridLayout 的属性 该栅格系统目前对 vue2 的支持是最好的,vue3 是需要用插件支持的,会在小节详细讲解…...

Electron(v26.2.1)无法加载React Developer Tools(v4.28.0)

一开始按照electron官网上的 开发者工具扩展 教程设置React Developer Tools时,重启项目后并没有按照预期成功加载React Developer Tools,而且控制台报错: Permission scripting is unknown or URL pattern is malformed.查了下原因是因为Re…...

网站降权的康复办法(详解百度SEO数据分析)

随着搜索引擎算法的不断升级,很多网站在SEO优化过程中遭遇到降权的情况。如果您的网站也遭遇到了类似的问题,不必惊慌失措。本文将为您详细介绍网站降权恢复的方法,包括百度SEO数据分析、网站收录少的5个原因、网站被降权的6个因素以及百度SE…...

非对称加密、解密原理及openssl中的RSA示例代码

一、【原理简介】非对称加密 非对称加密,也被称为公钥加密,其中使用一对相关的密钥:一个公钥和一个私钥。公钥用于加密数据,私钥用于解密数据。公钥可以公开分享,而私钥必须保密。 密钥生成: 当一个用户或设备希望使用…...

基于springboot漫画管理系统springboot001

摘 要 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息。为了迎合时代需求,优化管理效率,各种各样的管理系统应运而生,各行各业相继进入信息管理时代&…...

【探索C++】string类详解

(꒪ꇴ꒪ ),Hello我是祐言QAQ我的博客主页:C/C语言,数据结构,Linux基础,ARM开发板,网络编程等领域UP🌍快上🚘,一起学习,让我们成为一个强大的攻城狮&#xff0…...

python 第一次作业

1.使用turtle换一个五环 2.设计这样一个程序:输入一个数字 判断它是不是一个质数 使用turtle换一个五环: >>> import turtle #导入模块 >>> turtle.width(10) #设置圆圈宽度 >>> turtle.color("blue&qu…...

个人博客网站一揽子:Docker建站(Nginx、Wordpress、MySql)

前言 既然安装了Docker,那就不妨建立一个自己的博客网站。实现内外网隔离网站部署,更安全。 1.创建Docker子网络 首先创建一个Docker虚拟子网: sudo docker network create wpnt检查是否建立成功: sudo docker network ls最后…...

Unity 课时 4 : No.4 模拟面试题

课时 4 : No.4 模拟面试题 C# 1. 请说明字符串中 string str null string str “” string str string.Empty 三者的区别 第一个未作初始化没有值, 第二个为空字符串, 答案: str null 在堆中没有分配内存地址 str "" 和 string.Empty 一样都是…...

Golang 基础面试题 01

Golang 面试题合集.png 背景 在之前的文章中分享了 k8s 相关的面试题,本文我们重点来讨论和 k8s 密切相关的 Go 语言面试题。 这几年随着云原生的兴起,大部分后端开发者,特别是 Java 开发者都或多或少的想学习一些 Go 相关的技能,…...

007-第一代软件需求整理

第一代软件需求整理 文章目录 第一代软件需求整理项目介绍需求来源需求来源1:竞品软件分析需求来源2:医生(市场)需求来源3:项目组内部需求来源4:软件组内部需求来源5:软件开发成员需求来源6&…...

XMLHttpRequest介绍

目录 一、介绍1.创建 XMLHttpRequest2.初始化3.发送请求4.获取响应5.响应类型 二、发送GET请求示例三、发送POST请求示例四、发送POST请求下载文件示例五、发送POST请求上传文件示例 一、介绍 1.创建 XMLHttpRequest let xhr new XMLHttpRequest();2.初始化 xhr.open(metho…...

阿里云无影云电脑和传统PC有什么区别?

阿里云无影云电脑和传统电脑PC有什么区别?区别大了,无影云电脑是云端的桌面服务,传统PC是本地的硬件计算机,无影云电脑的数据是保存在云端,本地传统PC的数据是保存在本地客户端,阿里云百科分享阿里云无影云…...

基于matlab实现的船舶横摇运动仿真程序

完整程序: clc clear syms w we; w0.4:0.05:1.6;mu90;v6;%kb1;kt1;%航速6m/s,航向90度,即横浪,cos(90)0 T3;B10;Sw0.785;%船宽10米,吃水3米,水线面系数假设为0.785 weww.^2.*v/9.8; for i1:24 delta_we(i)we(i1)-…...

Java手写二叉索引树和二叉索引树应用拓展案例

Java手写二叉索引树和二叉索引树应用拓展案例 1. 算法思维导图 以下为二叉索引树的实现原理的思维导图,使用Mermanid代码表示: #mermaid-svg-raMRIu7t3H33MKh1 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#…...

大数据知识点之大数据5V特征

大数据的特征可以浓缩为五个英文单词,Volume(大量)、Variety(多样性)、Velocity(速度)、Value(价值)、Veracity(准确性)。因为是5个特征都是以“V”开头的英文单词,又叫大数据5V特征。 概述&…...

Java的Socket通信的断网重连的正确写法

Java的Socket通信的断网重连的正确写法 Socket通信的断网重连介绍客户端与服务端源码演示截图本地演示服务器演示演示截图 总结 Socket通信的断网重连介绍 针对于已经建立通信的客户端与服务器,当客户端与服务器因为网络问题导致网络不通而断开连接了或者由于服务器…...

ES6从入门到精通:前言

ES6简介 ES6(ECMAScript 2015)是JavaScript语言的重大更新,引入了许多新特性,包括语法糖、新数据类型、模块化支持等,显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

模型参数、模型存储精度、参数与显存

模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

代码规范和架构【立芯理论一】(2025.06.08)

1、代码规范的目标 代码简洁精炼、美观,可持续性好高效率高复用,可移植性好高内聚,低耦合没有冗余规范性,代码有规可循,可以看出自己当时的思考过程特殊排版,特殊语法,特殊指令,必须…...

Web后端基础(基础知识)

BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...

《Docker》架构

文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...

Vue3中的computer和watch

computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...