Java-常见面试题收集(四)

十 并发编程

1 Java 怎么保证多线程运行安全?

  线程安全是程序设计中的术语,指某个方法在多线程环境中被调用时,能正确的处理多个线程中的共享变量,使程序正确执行。Java 中线程安全体现在以下三个方面:
  原子性:提供互斥访问,同一时刻只能有一个线程对数据进行操作
  可见性:一个线程对主内存的修改可以及时地被其他线程看到
  有序性:一个线程观察其他线程中的指令执行顺序,由于指令重排序,该观察结果一般杂乱无序

  因此,只要满足上述三个条件,我们就可以说该代码是线程安全的。那么,Java 中提供了如下解决方案:
  使用 sychronized 关键字
  使用线程安全类,如:java.util.concurrent 包下的类
  使用并发包下 Lock 相关锁
  总结:想要代码满足线程安全,只需要代码满足原子性、可见性、有序性即可。

2 线程和进程的区别?Java 实现的多线程的方式有哪几种?

  线程和进程的区别: 进程是程序的一次动态执行过程,每个进程都有自己独立的内存空间。一个应用程序可以同时启动多个进程(比如浏览器可以开多个窗口,每个窗口就是一个进程)多进程操作系统能够运行多个进程,每个进程都能够循环利用所需要的 CPU 时间片,使的所有进程看上去像在同时运行一样。
  线程是进程的一个执行流程,一个进程可以由多个线程组成,也就是一个进程可以同时运行多个不同的线程,每个线程完成不同的任务。
  线程的并发运行:就是一个进程内若干个线程同时运行。(比如:word 的拼写检查功能和首字母自动大写功能是 word 进程中的线程)线程和进程的关系是一个局部和整体的关系,每个进程都由操作系统分配独立的内存地址空间,而同一进程的所有线程都在同一地址空间工作。
  多线程实现方式: Java 多线程实现方式主要有四种:继承 Thread 类、实现 Runnable 接口、实现 Callable 接口通过FutureTask 包装器来创建 Thread 线程、使用 ExecutorService、Callable、Future 实现有返回结果的多线程。
  继承 Thread 类,重写 run 方法
  实现 Runnable 接口,重写 run 方法,实现 Runnable 接口的实现类的实例对象作为 Thread 构造函数的 target
  通过 Callable 和 FutureTask 创建线程
  通过线程池创建线程

3 线程有哪些基本状态,并描述每种状态

  新建状态(New):当线程对象被创建时,它进入新建状态。此时,线程只是被创建,但还没有开始执行,也没有分配CPU时间,它只是一个尚未执行的任务。
  就绪状态(Ready或Runnable):当线程调用了start()方法后,它进入就绪状态。这意味着线程已经准备好运行,但还需要等待操作系统的调度,以获取CPU时间片。
  运行状态(Running):当线程被CPU选中并执行时,它进入运行状态。此时,线程正在执行其任务。
  阻塞状态(Blocked):当线程因为某种原因(例如等待I/O操作完成或进入sleep状态)无法继续执行时,它进入阻塞状态。在阻塞状态中,线程暂时放弃CPU的使用权,直到某种条件满足(例如I/O操作完成或sleep时间结束),线程重新进入就绪状态,等待CPU的调度。
  等待状态(Waiting):当线程需要等待其他线程执行完毕或者满足某个条件时,它会进入等待状态。例如,使用join方法时,当前线程会等待其他线程执行完毕。等待状态是线程主动放弃CPU使用权的一种形式。
  超时等待状态(Timed Waiting):这是等待状态的一种特殊形式。当线程使用sleep方法时,它会进入一个有时限的等待状态。如果超过了设定的时间,线程会自动醒来并进入就绪状态。
  终止状态(Terminated):当线程完成任务或被强制终止时,它进入终止状态。此时,线程释放所有资源,并且不再占用CPU时间。一旦线程进入终止状态,就不能再复生。

4 同步和异步的区别

  同步和异步是描述两个或多个操作之间如何相互关联和依赖的术语,特别是在编程和并发处理中。以下是同步和异步之间的主要区别:

  同步(Synchronous)同步操作意味着两个或多个操作按照特定的顺序一个接一个地执行,后面的操作需要等待前面的操作完成。有顺序性:操作按照预定义的顺序执行。阻塞性:如果某个操作需要花费一些时间来完成(例如,I/O操作),那么后续的操作将被阻塞,直到该操作完成。可预测性:因为操作按照预定的顺序执行,所以程序的行为通常更容易预测。在传统的函数调用中,调用者等待函数执行完毕并返回结果,然后才能继续执行后续的代码。

  异步(Asynchronous)异步操作允许两个或多个操作同时发生,不需要等待前一个操作完成。有并发性:操作可以同时开始,不需要等待其他操作完成。非阻塞性:一个操作的开始或结束不会阻塞其他操作的执行。不可预测性:由于操作的执行顺序和完成时间可能不确定,所以程序的行为可能更难以预测。异步I/O操作:当程序发起一个I/O请求(如读取文件或发送网络请求)时,它不需要等待操作完成就可以继续执行其他任务。当I/O操作完成时,程序会通过某种机制(如回调函数、Promise、Future或异步/等待语法)得到通知。

  同步与异步的比较
  性能:异步操作通常可以提高性能,因为在等待一个操作完成时,程序可以继续执行其他任务,从而充分利用资源。
  复杂性:异步编程通常比同步编程更复杂,因为需要处理操作的完成顺序、错误处理以及状态管理等问题。
  使用场景:同步操作适用于那些需要按照特定顺序执行且不需要等待的操作,例如简单的数学计算或内存操作。异步操作则适用于那些可能需要花费较长时间才能完成的操作,例如I/O操作、网络请求或长时间的计算任务。
  总的来说,同步和异步是处理操作顺序和依赖关系的不同方式,每种方式都有其适用场景和优缺点。在选择使用同步还是异步时,需要根据具体的应用需求、性能要求和编程复杂性进行权衡。

5 并发与并行的区别

并发与并行是计算机科学中描述多个任务或操作如何同时执行的概念,并发和并行的主要区别在于任务或操作是否在同一时刻真正同时发生,以及它们对CPU资源的利用方式。并发是在宏观上同时执行多个任务,但在微观上仍然是顺序执行;而并行则是多个任务在同一时刻真正同时执行。

6 线程的 run()和 start()有什么区别

  start() : 它的作用是启动一个新线程。通过 start()方法来启动的新线程,处于就绪(可运行)状态,并没有运行,一旦得到 cpu 时间片,就开始执行相应线程的 run()方法,这里方法 run()称为线程体,它包含了要执行的这个线程的内容,run 方法运行结束,此线程随即终止。start()不能被重复调用。用 start 方法来启动线程,真正实现了多线程运行,即无需等待某个线程的 run 方法体代码执行完毕就直接继续执行下面的代码。这里无需等待 run 方法执行完毕,即可继续执行下面的代码,即进行了线程切换。
  run() : run()就和普通的成员方法一样,可以被重复调用。如果直接调用 run 方法,并不会启动新线程!程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待 run 方法体执行完毕后才可继续执行下面的代码,这样就没有达到多线程的目的。
  总结:调用 start 方法方可启动线程,而 run 方法只是 thread 的一个普通方法调用,还是在主线程里执行。

7 runnable 和 callable 有什么区别

  runnable 没有返回值,而实现 callable 接口的任务线程能返回执行结果;callable 接口实现类中的 run 方法允许异常向上抛出,可以在内部处理,try catch,但是 runnable接口实现类中 run 方法的异常必须在内部处理,不能抛出

8 什么是线程死锁

  线程死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞现象。具体表现为,这些线程相互等待对方释放资源,但由于它们都持有对方所需的资源并不愿释放,导致了一个无解的循环等待状态。在这种情况下,若无外力作用,它们都将无法继续执行,系统因此处于死锁状态。死锁是多线程开发中应该坚决避免和杜绝的问题,因为它会导致程序无法正常终止,严重影响系统的性能和稳定性。

  线程死锁通常由以下四个必要条件造成:
  互斥条件:一个资源每次只能被一个线程使用。
  请求与保持条件:一个线程因请求资源而阻塞时,对已获得的资源保持不放。
  不可剥夺条件:线程已获得的资源,在未使用完之前,不能强行剥夺。
  循环等待条件:若干线程之间形成一种头尾相接的循环等待资源关系。
  解决线程死锁的方法主要是破坏这四个必要条件中的一个或多个。例如,可以通过确保线程在请求新资源前先释放已持有的资源,或者通过操作系统抢占某个线程的资源来打破循环等待等。

9 sleep() 方法和 wait() 方法区别和共同点

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

10 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行

  要确保线程 T2 在 T1 之后执行,并且 T3 在 T2 之后执行,可以使用线程同步机制。在 Java 中,可以使用 join() 方法来实现这种顺序执行。join() 方法的作用是让当前线程等待调用 join() 方法的线程执行完毕。下面是一个简单的 Java 示例代码:

public class ThreadOrdering {  public static void main(String[] args) {  Thread T1 = new Thread(() -> {  // T1 的任务  System.out.println("T1 执行完毕");  });  Thread T2 = new Thread(() -> {  try {  // 等待 T1 执行完毕  T1.join();  } catch (InterruptedException e) {  e.printStackTrace();  }  // T2 的任务  System.out.println("T2 执行完毕");  });  Thread T3 = new Thread(() -> {  try {  // 等待 T2 执行完毕  T2.join();  } catch (InterruptedException e) {  e.printStackTrace();  }  // T3 的任务  System.out.println("T3 执行完毕");  });  // 启动线程  T1.start();  T2.start();  T3.start();  }  
}

11 volatile 关键字的作用

  volatile关键字在编程中,特别是在多线程编程中,扮演着重要的角色。它的主要作用如下:

  保证变量的可见性:当一个线程修改了一个由volatile修饰的变量的值,其他线程可以立即看到这个修改。这是因为volatile关键字禁止了指令重排序,从而确保共享变量的修改对所有线程都是可见的。

  禁止指令重排序:编译器和处理器在编译和执行代码时,可能会对指令进行重排序以提高性能。然而,这种重排序有时会导致程序执行结果与预期不符。volatile关键字可以禁止这种重排序,保证程序按照预期的顺序执行,从而确保程序的正确性。

  保证原子性(在特定情况下):volatile关键字可以保证一些简单的操作的原子性,例如++操作。但是,对于复合操作,volatile关键字无法保证原子性。在多线程编程中,对于需要保证原子性的复杂操作,通常需要使用synchronized关键字或其他同步机制。

  需要注意的是,volatile关键字并不能完全替代其他的同步机制。在多线程编程中,应该根据具体情况选择使用volatile关键字或synchronized关键字等同步机制,以保证程序的正确性和效率。

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

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

相关文章

HCSC单片机使用小结

HCSC单片机使用小结 CAN 1、波特率主频/(分频1)/(SEG1SEG2)。存在BT寄存器中。 其中 2、STB在 FIFO 模式下,最先写入的数据先发送,在优先级模式下,ID 小的数据先发送。 3、通过 TCMD 寄存器的 TBSEL 位选…

巧用cpl文件维权和免杀(上)

cpl文件 CPL文件,是Windows控制面板扩展项,CPL全拼为Control Panel Item在system32目录下有一系列的cpl文件,分别对应着各种控制面板的子选项 列入我们winR输入main.cpl 将会打开控制面板中的鼠标属性 cpl文件本质是属于PE文件 但cpl并不像exe,更像是dl…

SQL107 将两个 SELECT 语句结合起来(二)(不用union,在where里用or)

select prod_id,quantity from OrderItems where quantity 100 or prod_id like BNBG% order by prod_id;在where子句里使用or

金蝶云星空和管易云单据接口对接

金蝶云星空和管易云单据接口对接 对接系统:管易云 管易云是金蝶旗下专注提供电商企业管理软件服务的子品牌,先后开发了C-ERP、EC-OMS、EC-WMS、E店管家、BBC、B2B、B2C商城网站建设等产品和服务,涵盖电商业务全流程。 写入目标:金蝶云星空 金…

【JAVA】super和this

super和this都可以在成员方法中用来访问:成员变量和调用其他的成员函数,都可以作为构造方法的第一条语 句 【相同点】 1. 都是Java中的关键字 2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段 3. 在构造方法中调用时&#…

[leetcode] 189. 轮转数组

给定一个整数数组 nums,将数组中的元素向右轮转 k 个位置,其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1,2,3,4,5,6] 向右轮转 2 步: [6,7,1,2,3,4,5] 向右轮转 3 步: [5,6,7,1,2,3,…

CentOS7安装mysql-5.7.44单机和主从复制

官网下载地址: https://downloads.mysql.com/archives/community/ 1、单机安装 安装依赖 yum -y install libaio 解压安装 tar -zxvf mysql-5.7.44-linux-glibc2.12-x86_64.tar.gzmv mysql-5.7.44-linux-glibc2.12-x86_64 /usr/local/mysqlcd /usr/local/mysql…

前端开发常用判断符号

!就是将右侧值先转化为bool值后在进行取反,因此对于空对象或者空数组的取反取值为false,因为空对象或空数组转化为bool值为true。 !!则为在一个!将右侧值转化为bool值取反后再取反。 |该运算符取值逻辑为判断时将值转化为bool值判断左侧值为true or fa…

文件上传一-WEB攻防-PHP应用文件上传函数缺陷条件竞争二次渲染黑白名单JS绕过9

演示案例: PHP-原生态-文件上传-前后端验证PHP-原生态-文件上传-类型文件头验证PHP-原生态-文件上传-后缀黑白名单验证PHP-原生态-文件上传-解析配置&二次渲染PHP-原生态-文件上传-逻辑缺陷&函数缺陷 #学习前必读: 1、课前一定要明白&#xff1a…

蓝桥杯基础练习详细解析一(代码实现、解题思路、Python)

试题 基础练习 数列排序 资源限制 内存限制&#xff1a;512.0MB C/C时间限制&#xff1a;1.0s Java时间限制&#xff1a;3.0s Python时间限制&#xff1a;5.0s 问题描述 给定一个长度为n的数列&#xff0c;将这个数列按从小到大的顺序排列。1<n<200 输入格式 第…

MySQL事务(超详细!!!)

目录 一、MySQL事务的概念 二、事务的ACID特点 1、原子性&#xff08;Atomicity&#xff09; 2、持久性 3、隔离性&#xff08;Isolation&#xff09; 3.1 事务的并发问题 ①、脏读(读取未提交数据) ②读已提交、不可重复读(前后多次读取&#xff0c;数据内容不一致) …

【Redis主从架构。主从工作原理psync、bgsave、部分数据复制、主从复制风暴解决方案】【Redis哨兵高可用架构。sentinel】

Redis主从架构 Redis主从工作原理数据部分复制 Redis哨兵高可用架构client连接哨兵规则主节点挂了&#xff0c;集群从新选择主节点&#xff0c;并且同步给sentinel 转自图灵课堂 redis主从架构搭建&#xff0c;配置从节点步骤&#xff1a; 1、复制一份redis.conf文件2、将相关…

美易官方:除了散户,对冲基金也在重返加密市场

高盛&#xff1a;除了散户&#xff0c;对冲基金也在重返加密市场 随着加密货币市场的逐渐成熟和技术的不断进步&#xff0c;越来越多的机构投资者开始重新审视加密货币市场。除了散户投资者外&#xff0c;对冲基金也在重返加密市场&#xff0c;成为市场的重要参与者之一。高盛作…

苹果手机强制重启方法大揭秘!不同机型多种方法一网打尽

随着苹果手机的普及&#xff0c;越来越多的人选择使用这款优秀的智能手机。然而&#xff0c;就像任何其他设备一样&#xff0c;苹果手机也可能会出现各种问题&#xff0c;例如系统崩溃、应用程序冻结或其他错误。在这种情况下&#xff0c;强制重启手机是解决问题的一个有效方法…

Pygame基础3-动画

3.动画 原理 动画是连续播放的图片。 使用精灵显示动画只需要在update()方法中改变精灵的图片。 需要注意的是播放速度&#xff0c;可以 通过pygame.time.get_ticks()来控制时间&#xff0c;但是这样比较复杂。最直接的方式是根据帧数来控制播放。每过n帧就切换一次图片。 …

linux系统--------------mysql数据库管理

目录 一、SQL语句 1.1SQL语言分类 1.2查看数据库信息 1.3登录到你想登录的库 1.4查看数据库中的表信息 1.5显示数据表的结构&#xff08;字段&#xff09; 1.5.1数据表的结构 1.5.2常用的数据类型: 二、关系型数据库的四种语言 2.1DDL&#xff1a;数据定义语言&am…

linux内核原理-共享内存,信号

1.共享内存 (1). 定义 在Linux中&#xff0c;进程间通信&#xff08;IPC&#xff09;有多种方式&#xff0c;其中共享内存&#xff08;Shared Memory&#xff09;是一种非常高效的方式。它允许两个或多个进程共享同一块物理内存区域&#xff0c;从而可以快速地传递大量数据。 …

CentOS 8 中安装与配置 MySQL

本文将详细介绍如何在 CentOS 8 系统上安装 MySQL&#xff0c;并对其进行基础安全配置&#xff0c;包括设置 root 密码、移除匿名用户、禁止 root 远程登录等。 步骤一&#xff1a;安装 MySQL 服务器 利用 CentOS 8 自带的 dnf 包管理器安装 MySQL 服务器&#xff1a; sudo …

【二十一】【算法分析与设计】位运算(2)

137. 只出现一次的数字 II 给你一个整数数组 nums &#xff0c;除某个元素仅出现 一次 外&#xff0c;其余每个元素都恰出现 三次 。请你找出并返回那个只出现了一次的元素。 你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。 示例 1&#xff1a; 输入&…

Web安全基础入门+信息收集篇

教程介绍 学习信息收集&#xff0c;针对域名信息,解析信息,网站信息,服务器信息等&#xff1b;学习端口扫描&#xff0c;针对端口进行服务探针,理解服务及端口对应关系&#xff1b;学习WEB扫描&#xff0c;主要针对敏感文件,安全漏洞,子域名信息等&#xff1b;学习信息收集方法…