【大厂真题】并发编程面试集合(一)

简介: 并发编程面试

1、synchronized用过吗,其原理是什么

这是一道Java面试中几乎百分之百都会问到的题目,如果没有参与过并发编程的话,对其是说不上来的。synchronized是由JVM实现的一种实现互斥同步的方式

Synchronized是由JVM实现的一种实现互斥同步的一种方式,如果你查看被Synchronized修饰过的程序块编译后的字节码,会发现,被Synchronized修饰过的程序块,在编译前后被编译器生成了monitorenter和monitorexit两个字节码指令。

在虛拟机执行到monitorenter指令时,首先要尝试获取对象的锁:

  • 如果这个对象没有锁定,或者当前线程已经拥有了这个对象的锁,把锁的计数器+1;
  • 当执行 monitorexit指令时将锁计数器-1;
  • 当计数器为O时,锁就被释放了。如果获取对象失败了,那当前线程就要阻塞等待,直到对象锁被另外一个线程释放为止。
  • Java中Synchronize通过在对象头设置标记,达到了获取锁和释放锁的目的。

2、你刚才提到获取对象的锁,这个锁是什么?如何确定对象的锁?

“锁”的本质其实是monitorenter和monitorexit字节码指令的一个Reference类型的参数,即要锁定和解锁的对象。我们知道,使用Synchronized可以修饰不同的对象,因此,对应的对象锁可以这么确定。

  • 如果Synchronized明确指定了锁对象,比如Synchronized(变量名)、Synchronized(this)等,说明加解锁对象为该对象。
  • 如果没有明确指定:
  • 若Synchronized修饰的方法为非静态方法,表示此方法对应的对象为锁对象;
  • 若Synchronized修饰的方法为静态方法,则表示此方法对应的类对象为锁对象;

3、什么是可重入性?为什么说synchronized是可重入锁?

所谓可重入就是说某个线程已经获得某个锁,可以再次获取锁而不会出现死锁。

synchronized是基于原子性的内部锁机制,是可重入的,因此在一个线程调用synchronized方法的同时在其方法体内部调用该对象另一个synchronized方法,也就是说一个线程得到一个对象锁后再次请求该对象锁,是允许的,这就是synchronized的可重入性。

4、Java中的线程池是如何实现的?

线程是稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,合理的使用线程池对线程进行统一分配、调优和监控,有以下好处:

  • 1、降低资源消耗;
  • 2、提高响应速度;
  • 3、提高线程的可管理性。

Executors是java线程池的工厂类,通过它可以快速初始化一个符合业务需求的线程池,如Executors.newFixedThreadPool方法可以生成一个拥有固定线程数的线程池。

其本质是通过不同的参数初始化一个ThreadPoolExecutor对象,具体参数描述如下:

corePoolSize

线程池中的核心线程数,当提交一个任务时,线程池创建一个新线程执行任务,直到当前线程数等于corePoolSize;如果当前线程数为corePoolSize,继续提交的任务被保存到阻塞队列中,等待被执行;如果执行了线程池的prestartAllCoreThreads()方法,线程池会提前创建并启动所有核心线程。

maximumPoolSize

线程池中允许的最大线程数。如果当前阻塞队列满了,且继续提交任务,则创建新的线程执行任务,前提是当前线程数小于maximumPoolSize;

keepAliveTime

线程空闲时的存活时间,即当线程没有任务执行时,继续存活的时间;默认情况下,该参数只在线程数大于corePoolSize时才有用;

workQueue

用来保存等待被执行的任务的阻塞队列,且任务必须实现Runable接口,在JDK中提供了如下阻塞队列:

  • 1、ArrayBlockingQueue:基于数组结构的有界阻塞队列,按FIFO排序任务;
  • 2、LinkedBlockingQuene:基于链表结构的阻塞队列,按FIFO排序任务,吞吐量通常要高于ArrayBlockingQuene;
  • 3、SynchronousQuene:一个不存储元素的阻塞队列,每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常要高于LinkedBlockingQuene;
  • 4、priorityBlockingQuene:具有优先级的无界阻塞队列;

5、如何在java线程池中提交线程?

线程池框架提供了两种方式提交任务,根据不同的业务需求选择不同的方式。

Executor.execute()

在这里插入图片描述

通过Executor.execute()方法提交的任务,必须实现Runnable接口,该方式提交的任务不能获取返回值,因此无法判断任务是否执行成功。

ExecutorService.submit()

在这里插入图片描述

通过ExecutorService.submit()方法提交的任务,可以获取任务执行完的返回值。

相关文章
|
1月前
|
决策智能
集合-Nim游戏(面试hard博弈论)
集合-Nim游戏(面试hard博弈论)
|
1月前
|
开发工具 Python 容器
2024年最全python进阶系列- 04 集合(1),面试高频问题回答
2024年最全python进阶系列- 04 集合(1),面试高频问题回答
2024年最全python进阶系列- 04 集合(1),面试高频问题回答
|
1月前
|
数据采集 关系型数据库 MySQL
2024年最全python进阶系列- 04 集合,2024年最新哈希表 面试
2024年最全python进阶系列- 04 集合,2024年最新哈希表 面试
|
15天前
|
存储 安全 算法
Java基础19-一文搞懂Java集合类框架,以及常见面试题(二)
Java基础19-一文搞懂Java集合类框架,以及常见面试题(二)
41 8
|
15天前
|
安全 Java 开发工具
Java基础19-一文搞懂Java集合类框架,以及常见面试题(一)
Java基础19-一文搞懂Java集合类框架,以及常见面试题(一)
35 6
|
17天前
|
存储 缓存 算法
【面试宝藏】Go并发编程面试题
探索Go语言并发编程,涉及Mutex、RWMutex、Cond、WaitGroup和原子操作。Mutex有正常和饥饿模式,允许可选自旋优化。RWMutex支持多个读取者并发,写入者独占。Cond提供goroutine间的同步,WaitGroup等待任务完成。原子操作保证多线程环境中的数据完整性,sync.Pool优化对象复用。了解这些,能提升并发性能。
16 2
|
1天前
|
安全 Java API
《面试专题-----经典高频面试题收集三》解锁 Java 面试的关键:深度解析并发编程基础篇高频经典面试题(第三篇)
《面试专题-----经典高频面试题收集三》解锁 Java 面试的关键:深度解析并发编程基础篇高频经典面试题(第三篇)
5 0
|
1月前
|
机器学习/深度学习 数据采集 自然语言处理
2024年Python最新【python开发】并发编程(下),2024年最新字节跳动的面试流程
2024年Python最新【python开发】并发编程(下),2024年最新字节跳动的面试流程
2024年Python最新【python开发】并发编程(下),2024年最新字节跳动的面试流程
|
1月前
|
安全 Go 开发者
Golang深入浅出之-Go语言并发编程面试:Goroutine简介与创建
【4月更文挑战第22天】Go语言的Goroutine是其并发模型的核心,是一种轻量级线程,能低成本创建和销毁,支持并发和并行执行。创建Goroutine使用`go`关键字,如`go sayHello("Alice")`。常见问题包括忘记使用`go`关键字、不正确处理通道同步和关闭、以及Goroutine泄漏。解决方法包括确保使用`go`启动函数、在发送完数据后关闭通道、设置Goroutine退出条件。理解并掌握这些能帮助开发者编写高效、安全的并发程序。
32 1
|
1月前
|
Java
面试官:集合使用时应该注意哪些问题?我:应该注意该注意的问题!
面试官:集合使用时应该注意哪些问题?我:应该注意该注意的问题!
23 1