面试八股文(4)

news2024/12/24 11:34:54

文章目录

      • 1.sleep和wait区别
      • 2.为什么调用start()方法会执行run()方法,为什么不能直接调用run()方法
      • 3.synchronized关键字
      • 4.并发编程的三个重要特性
      • 5.synchronized和volatile关键字区别
      • 6.ThreadLocal
      • 7.为什么要用线程池?
      • 8.实现Runnable接口和Callable接口的区别
      • 9.执行execute()和submit()方法区别
      • 10.如何创建线程池

1.sleep和wait区别

  • 两者最主要的区别在于:sleep方法没有释放锁,而wait方法释放了锁。
  • 两者都可以暂停线程的执行。
  • wait通常被用于线程间交互、通信,sleep通常被用于暂停执行。
  • wait()方法被调用后,线程不会自动苏醒,需要别的线程调用同一个对象的notify()或者notifyAll()方法。sleep()方法执行完毕后,线程会自动苏醒,或者可以使用wait(long timeout)超时后线程会自动苏醒。

2.为什么调用start()方法会执行run()方法,为什么不能直接调用run()方法

当我们new一个Thread,线程进入新建状态;调用start()方法,会启动一个线程并使线程进入了就绪状态,当分配到时间片后就可以开始运行了。start()会执行线程相应的准备工作,然后自动执行run()方法的内容,这是真正的多线程工作。而直接执行run()方法,会把run()方法当成有一个main线程下的普通方法执行,并不会在某个线程中执行它,所以这并不是多线程工作。

总结:调用start方法方可启动线程并使线程进入就绪状态,而run方法只是thread的一个普通方法调用,还是在主线程里执行

3.synchronized关键字

synchronized关键字解决的是多个线程之间访问资源的同步性,synchronized关键字可以保证被它修饰的方法或者代码块在任意时刻只能有一个线程执行。

synchronized关键字最主要的三种使用方式:

  • 修饰实例方法:作用于当前对象实例加锁,进入同步代码前要获得当前对象实例的锁。
  • 修饰静态方法:也就是给当前类加锁,会作用于类的所有实例对象,因为静态成员不属于任何一个实例对象,是类成员(static表明这是该类的一个静态资源,不管new了多少个对象,只有一份)。所以如果一个线程A调用一个实例对象的非静态synchronized方法,而线程B需要调用这个实例对象所属类的静态synchronized方法,是允许的,不会发生互斥现象,因为访问静态synchronized方法占用的锁是当前类的锁,而访问非静态synchronized方法占用的是当前实例对象锁
  • 修饰代码块:指定加锁对象,对给定对象加锁,进入同步代码库前妖狐的给定对象的锁。

总结:synchronized关键字加到static静态方法和synchronized代码块上都是给Class类上锁。synchronized关键字加到实例方法是给对象实例上锁。尽量不要使用synchronized(String a)因为JVM中,字符串常量池具有缓存作用。

4.并发编程的三个重要特性

  1. 原子性:一次操作或者多次操作,要么所有的操作全部得到执行并不会受到任何因素的干扰而中断,要么所有的操作都执行,要么都不执行。synchronized可以保证代码片段的原子性。
  2. 可见性:当一个变量对共享变量进行了修改,那么另外的线程都是立即可以看到修改后的最新值。volatile关键字可以保证共享变量的可见性。
  3. 有序性:代码在执行的过程中的先后顺序,Java在编译器以及运行期间的优化,代码的执行顺序未必就是编写代码时候的顺序。volatile关键字可以禁止指令进行重排序优化。

5.synchronized和volatile关键字区别

  • volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用synchronized关键字的场景还是多一些。
  • 多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞。
  • volatile关键字能保证数据的可见性,但不能保证数据的原子性,synchronized关键字两者都能保证。
  • volatile关键字主要用于解决变量在多个线程之间的可见性,而synchronized关键字解决的是多个线程之间访问资源的同步性。

6.ThreadLocal

通常情况下,我们创建的线程是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决?JDK中提供的ThreadLocal类正是为了解决这样的问题。ThreadLocal类主要解决的就是让每个线程绑定自己的值,可以将ThreadLocal类形象的比喻成存放数据的盒子,盒子中存储每个线程的私有数据。

如果你创建了一个ThreadLocal变量,那么可以访问这个变量的每个线程都会有这个变量的本地副本,这也是ThreadLocal变量名的由来。他们可以使用get()和set()方法来获取默认值或将其值更改为当前线程所存的副本的值,从而避免了线程安全问题。

7.为什么要用线程池?

线程池提供了一种限制和管理资源(包括执行一个任务)。每个线程池还维护一些基本统计信息,例如已完成任务的数量。

使用线程池的好处:

  • 降低资源消耗:通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
  • 提高响应速度:当任务到达时,任务可以不需要等到线程创建就能立即执行。
  • 提高线程的可管理性:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配、调优和监控。

8.实现Runnable接口和Callable接口的区别

Runnable自Java1.0以来一直存在,但Callable仅在Java1.5中引入,目的就是为了来处理Runnable不支持的用例。Runnable接口不会返回结果或抛出检查异常,但是Callable接口可以。所有如果任务不需要返回结果或抛出异常推荐使用Runnable接口,这样代码看起来更加简洁。

@FunctionalInterface
public interface Runnable {
	public abstract void run();
}
@FunctionalInterface
public interface Callable<V> {
	V call() throws Exception;
}

工具类Executors可以实现Runnable对象和Callable对象之间的相互转换。
Executors.callable(Runnable task)或Executors.callable(Runnable task,Object resule)

9.执行execute()和submit()方法区别

  • execute()方法用于提交不需要返回值的任务,所以无法判断任务是否被线程池执行成功与否。
  • submit()方法用于提交需要返回值的任务,线程池会返回一个Future类型的对象,通过这个Future对象可以判断任务是否执行成功,并且可以通过Future的get()方法来获取返回值,get()方法会阻塞当前线程直到任务完成,而使用get(long timeout,TimeUnit unit)方法则会阻塞当前线程一段时间后立即返回,这时候有可能任务没有执行完。

10.如何创建线程池

一般强制线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样处理让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

通过构造方法实现

在这里插入图片描述
通过Executor框架的工具类Executors来实现
我们可以创建三种类型的ThreadPoolExecutor:

  • FixedThreadPool:该方法返回一个固定线程数量的线程池。该线程池中的线程数量始终不变。当有一个新的任务提交时,线程池中若有空闲的线程,则立即执行。若没有,则新的任务会被暂存在一个任务队列中,待有线程空闲时,便处理在任务队列中的任务。
  • SingleThreadExecutor:该方法返回一个只有一个线程的线程池。若多于一个任务被提交到该线程池,任务会被保存在一个任务队列中,待线程空闲,按先入先出的顺序执行队列中的任务。
  • CacheThreadPool:该方法返回一个可根据实际情况调整线程数量的线程池。线程池的线程数量不确定,但若有空闲线程可以服用,则优先使用可复用的线程。若所有线程均在工作,又有新的任务提交,则会创建新的线程处理任务。所有线程在当前任务执行完毕后,将返回线程池进行复用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1429489.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据图表方案,企业视频生产数据可视化

在信息爆炸的时代&#xff0c;如何将复杂的数据转化为直观、生动的视觉信息&#xff0c;是企业在数字化转型中面临的挑战。美摄科技凭借其独特的数据图表方案&#xff0c;为企业在数据可视化领域打开了一扇全新的大门。 一、数据图表方案的优势 1、高效便捷&#xff1a;利用数…

模拟钉钉官网动画

实现思路&#xff1a;利用粘性定位sticky&#xff0c;以及滚动事件实现。首先我们应该设置滚动动画开始位置和结束位置 &#xff0c;然后根据位置计算透明度或者transform&#xff0c;scale的值。 首先根据上述图线计算属性值&#xff0c;代码如下&#xff1a; function creat…

技术分享 | app测试中常用的Android模拟器

Emulator Emualor 是 Android Studio 自带的模拟器&#xff0c;是官方提供的工具&#xff0c;Android 开发最常使用的就是这一款。 它功能非常齐全&#xff0c;电话本、通话等功能都可正常使用。用户可以使用键盘输入&#xff0c;鼠标点击模拟器按键输入&#xff0c;甚至还可…

DockerCompose+SpringBoot+Nginx+Mysql实践

DockerComposeSpringBootNginxMysql实践 1、Spring Boot案例 首先我们先准备一个 Spring Boot 使用 Mysql 的小场景&#xff0c;我们做这样一个示例&#xff0c;使用 Spring Boot 做一个 Web 应 用&#xff0c;提供一个按照 IP 地址统计访问次数的方法&#xff0c;每次请求时…

Docker部署xxl-job调度器并结合SpringBoot测试

文章目录 一、Docker部署1. 创建数据库2. 启动容器3. 访问4. 新建执行器 二、SpringBoot整合1. 模块注册到执行器2. 创建配置类3. 启动测试 三、任务发布-普通任务1. 编写任务代码2. 创建任务3. 启动任务 四、任务发布-分片任务1. 编写任务代码2. 启动多个实例3. 创建任务4. 启…

机器学习复习(2)——线性回归SGD优化算法

目录 线性回归代码 线性回归理论 SGD算法 手撕线性回归算法 模型初始化 定义模型主体部分 定义线性回归模型训练过程 数据demo准备 模型训练与权重参数 定义线性回归预测函数 定义R2系数计算 可视化展示 预测结果 训练过程 sklearn进行机器学习 线性回归代码…

浙政钉(专有钉钉)

专有钉钉是浙政钉的测试版本&#xff0c;可在正式发布之前进行业务开发。 专有钉钉 原名政务钉钉 是高安全、强管控、灵活开放的面向大型组织专有独享的协同办公平台。支持专有云、混合云等多种方式灵活部署&#xff0c;以满足客户特定场景所需为目标&#xff0c;最大化以“平…

elk之简介

写在前面 本文看下es的简介。 1&#xff1a;简介 背后公司&#xff0c;elastic&#xff0c;08年纽交所上市&#xff0c;与腾讯&#xff0c;阿里等云厂商有合作&#xff0c;推出云产品&#xff0c;类似功能的产品由solr&#xff0c;splunk&#xff0c;但使用量es当前遥遥领先…

Vue-52、Vue技术插槽使用

1、默认插槽 App.vue <template><div class"container"><category title"美食"><img src"https://tse2-mm.cn.bing.net/th/id/OIP-C.F0xLT-eKcCSOI5tdjBv9FAHaE8?w303&h202&c7&r0&o5&pid1.7">&l…

网络安全之SSL证书加密

简介 SSL证书是一种数字证书&#xff0c;遵守SSL协议&#xff0c;由受信任的数字证书颁发机构&#xff08;CA&#xff09;验证服务器身份后颁发。它具有服务器身份验证和数据传输加密的功能&#xff0c;能够确保数据在传输过程中的安全性和完整性。 具体来说&#xff0c;SSL证…

番外篇 vue与django 交互流程

学习了一段时间的django和vue&#xff0c;对于前后端开发有了一个初步的了解&#xff0c;这里记录一下编写的流程和思路&#xff0c;主要是为了后面如果遗忘从哪里开始操作做一个起步引导作用 一、Django后端 参考下前面django的文档https://moziang.blog.csdn.net/article/det…

Web实战丨基于django+hitcount的网页计数器

文章目录 写在前面Django简介主要程序运行结果系列文章写在后面 写在前面 本期内容 基于djangohitcount的网页计数器 所需环境 pythonpycharm或vscodedjango 下载地址 https://download.csdn.net/download/m0_68111267/88795611 Django简介 Django 是一个开源的、基于 …

六、Nacos源码系列:Nacos健康检查

目录 一、简介 二、健康检查流程 2.1、健康检查 2.2、客户端释放连接事件 2.3、客户端断开连接事件 2.4、小结 2.5、总结图 三、服务剔除 一、简介 Nacos作为注册中心不止提供了服务注册和服务发现的功能&#xff0c;还提供了服务可用性检测的功能&#xff0c;在Nacos…

【QT+QGIS跨平台编译】之二十二:【FontConfig+Qt跨平台编译】(一套代码、一套框架,跨平台编译)

文章目录 一、FontConfig介绍二、文件下载三、文件分析四、pro文件五、编译实践 一、FontConfig介绍 FontConfig 是一个用于配置和定制字体的库&#xff0c;广泛应用于基于X Window系统的操作系统中&#xff0c;尤其是在Linux和Unix-like系统中。它为应用程序提供了一种统一的…

在VM虚拟机搭建NFS服务器

NFS共享要求如下&#xff1a; &#xff08;1&#xff09;共享“/mnt/自已姓名的完整汉语拼音”目录&#xff0c;允许XXX网段的计算机访问该共享目录&#xff0c;可进行读写操作。&#xff08;说明&#xff1a;XXX网段&#xff0c;请根据你的规划&#xff0c;再具体指定&#xf…

2024美赛数学建模B题思路分析 - 搜索潜水器

# 1 赛题 问题B&#xff1a;搜索潜水器 总部位于希腊的小型海上巡航潜艇&#xff08;MCMS&#xff09;公司&#xff0c;制造能够将人类运送到海洋最深处的潜水器。潜水器被移动到该位置&#xff0c;并不受主船的束缚。MCMS现在希望用他们的潜水器带游客在爱奥尼亚海底探险&…

STM32F1 - 存储器映射

Memory mapping 1> 外设内存地址映射2> GPIO寄存器映射3> 存储器访问 1> 外设内存地址映射 1> STM32F103ZET6的地址线位宽为32位&#xff0c;所以寻址空间为4GB &#xff08;2 ^ 32 4GB&#xff09;&#xff1b; 2> STM32将&#xff0c;Flash&#xff0c;SR…

数仓建模维度建模理论知识

0. 思维导图 第 1 章 数据仓库概述 1.1 数据仓库概述 数据仓库是一个为数据分析而设计的企业级数据管理系统。数据仓库可集中、整合多个信息源的大量数据&#xff0c;借助数据仓库的分析能力&#xff0c;企业可从数据中获得宝贵的信息进而改进决策。同时&#xff0c;随着时间的…

【经典项目】Java小游戏 —— 弹力球

一、功能需求 设计一个Java弹球小游戏的思路如下&#xff1a; 创建游戏窗口&#xff1a;使用Java图形库&#xff08;如Swing或JavaFX&#xff09;创建一个窗口&#xff0c;作为游戏的可视化界面。 绘制游戏界面&#xff1a;在游戏窗口中绘制游戏所需的各个元素&#xff0c;包括…

同城外卖跑腿app开发:重新定义城市生活

随着科技的发展和人们生活节奏的加快&#xff0c;同城外卖跑腿app应运而生&#xff0c;成为现代城市生活中的重要组成部分。本文将探讨同城外卖跑腿app开发的意义、市场需求、功能特点以及未来的发展趋势。 一、同城外卖跑腿app开发的意义 同城外卖跑腿app作为一种便捷的生活…