面试锦集:手写一个同步类容器之Lock/Condition await signalAll实现

Java面试核心知识点与高效复习策略:从原理到实战 在软件开发领域,扎实的技术基础和高效的复习方法是求职成功的关键。理解核心概念如数据结构、算法和系统设计原理,是构建稳定、高性能应用的基础。这些原理通过具体的技术实现其价值,例如在Java生态中,HashMap的数据结构设计直接影响数据存取效率,而JVM的垃圾回收机制则关乎应用性能与稳定性。掌握这些技术,能有效应对高并发、大数据量等实际应用场景的挑战。本文聚焦Java面试,深入解析HashMap的底层实现与扩容机制、JVM内存模型与GC算法等核心热词,并提供从知识点到场景应用的复习路径,帮助开发者构建系统化的 阅读详情

互联网大厂面试必考题目:

手写一个同步类容器,支持多个生产者线程以及多个消费者线程的阻塞调用。采用 Lock/Condition await signalAll实现,更精确定位唤起的线程。我第一次去大厂面试都被难住了!!!

package com.container;

import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 面试锦集:手写一个同步类容器(互联网大厂面试题目)
 * 
 * 支持多个生产者线程以及多个消费者线程的阻塞调用,采用Lock/Condition await signalAll实现 更精确定位唤起的线程
 * 
 * @author 小辉GE/小辉哥
 * 
 * 2019年8月8日 下午20:30:00
 */
public class ContainerReentrantLock {
	// 最少0个元素
	private final int MIN_SIZE = 0;
	// 最多20个元素
	private final int MAX_SIZE = 20;
	// 定义容器size的计算器
	private final AtomicInteger atomic = new AtomicInteger(0);
	// 定义装载容器
	private final LinkedList<Object> container = new LinkedList<Object>();
	// 定义Lock
	private Lock lock = new ReentrantLock();
	// 定义Condition
	private Condition producer = lock.newCondition();
	private Condition consumer = lock.newCondition();

	public void put(Object obj) {
		try {
			lock.lock();
			while (atomic.get() == MAX_SIZE) {
				producer.await();
			}
			// 添加元素
			container.add(obj);
			// 计数器
			atomic.incrementAndGet();
			// 通知所有消费者线程进行消费
			consumer.signalAll();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
	}

	public Object get() {
		Object result = null;
		try {
			lock.lock();
			while (atomic.get() == MIN_SIZE) {
				consumer.await();
			}
			result = container.removeFirst();
			atomic.decrementAndGet();
			// 通知所有生产者线程进行生产
			producer.signalAll();
		} catch (InterruptedException e) {
			e.printStackTrace();
		} finally {
			lock.unlock();
		}
		return result;
	}

	public static void main(String[] args) {
		ContainerReentrantLock lock = new ContainerReentrantLock();
		// 启动消费者线程
		for (int i = 0; i < 10; i++) {
			new Thread(() -> {
				for (int j = 0; j < 10; j++) {
					System.out.println("消费者" + Thread.currentThread().getName() + ",获取数据为:" + lock.get());
				}
			}, "consumer" + i).start();
		}

		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		// 启动生产者线程
		for (int i = 0; i < 5; i++) {
			new Thread(() -> {
				for (int j = 0; j < 20; j++) {
					int data = (int) (Math.random() * 1000);
					lock.put(data);
					System.out.println("生产者" + Thread.currentThread().getName() + ",存放数据为:" + data);
				}
			}, "producer" + i).start();
		}
	}
}

测试输出结果如下(输出结果比较多,我们只截取部分):

从结果可以看出生产者和消费者线程是交替输出的。关于Lock/Condition await signalAll实现方式还不明白的同学,详情可以在我的头条号‘小辉GE’查看对应‘手写一个同步类容器(互联网大厂面试题目)’视频,里面有详细讲解。

以上代码仅供参考,如有不当之处,欢迎指出!!!

更多干货,欢迎大家关注和联系我。期待和大家一起更好的交流、探讨技术!!!

 

腾讯四大方向面经汇总:前端、Java、C++、Go全解析 技术面试的底层逻辑,往往藏在各语言、框架的表象之下。无论是浏览器渲染机制、JVM内存模型、C++的RAII与移动语义,还是Go的GMP并发调度,大厂面试官真正考察的都是候选人“理解原理并落地决策”的能力。并发编程、性能优化、容器与数据结构这些高频考点,在不同技术栈中呈现出共通的考察维度——从基础八股到项目深挖,从手写代码到方案选型,每轮面试都在验证你能否在复杂工程中做出正确取舍。本文基于真实面试经历,完整复盘腾讯前端、Java、C++、Go四个方向的核心题目、追问链与答题思路,并横向对比各方向考察重点,提炼 阅读详情

相关推荐

Java SE 8核心原理与生产级面试深度解析

Java SE 8是JVM生态中兼容性、稳定性与现代化编程范式交汇的基石版本。其Lambda表达式依托invokedynamic指令实现字节码兼容演进,Stream API则在惰性求值与短路机制中嵌入运行时优化逻辑;而G1垃圾收集器、逃逸分析、锁升级等JVM特性共同构成高性能服务的底层支撑。理解这些机制,不仅关乎语法掌握,更决定能否在金融、政务等高可靠场景中规避类加载失败、内存泄漏、GC风暴等典型故障。本文聚焦Java 8不可替代的工程价值,结合Lambda本质、Stream性能陷阱、JVM调优实战等高频技

weixin_30908103的博客 484

手写async await的最简实现(20行搞定)!阿里字节面试必考

前言作者:ssh,来源:前端从进阶到入院原文地址:https://juejin.im/post/5e79e841f265da5726612b6e如果让你手写async函数的实现,你是不是...

程序员成长指北 4680

Java并发编程核心:JUC工具包深度解析与实战指南

并发编程是构建高性能、高可用Java应用的核心技术,其核心挑战在于多线程环境下对共享资源的安全访问与高效协调。Java通过内置的synchronized关键字和wait/notify机制提供了基础的同步能力,但在面对复杂的生产环境时,这些基础工具在灵活性、性能和功能上往往力不从心。为此,Java 5.0引入了java.util.concurrent(JUC)工具包,它提供了一套工业级的并发解决方案,其价值在于将开发者从基础的线程同步层面,提升到能够优雅、高效地组织大规模线程协同工作的工程实践层面。JUC的核

weixin_33834137的博客 501

Lock的condition的await、signal/signalAll的机制,以及各种队列变化

acquireQueued(node,savedSate)这个在AQS解析过,就是进入同步双向队列,这个方法怎么都要执行,没有拿到锁就park等待,拿到锁就出队返回,这里只看返回true或false,但不重要,这里的判断条件是 && ,只看interruptMode ,中间这步不看,还是清理cancelNode,看最后,是哪样就返回哪样,selfInterrupt()的话,就是interrupt是signal之后执行,这里只是还原用户操作,和AQS那里是一致。,自己就进入condition的等待队列。

chuyouyinghe的专栏 807

BlenderGis安装碰到问题,ImageIO、无法点击和地图不加载

BlenderGis安装碰到问题,ImageIO、无法点击和地图不加载问题

qq_45176349的博客 4964

iPhone用户必看:不装App也能搞定GitHub 2FA验证的3种方法(附恢复码管理技巧)

本文为iPhone用户提供了无需安装第三方App即可完成GitHub双重身份验证(2FA)的三种原生方案:利用相机扫码与iCloud钥匙串自动填充、使用iCloud钥匙串内置的TOTP验证码生成器,以及借助Safari浏览器扩展。文章详细解析了每种方法的操作步骤、适用场景,并重点强调了恢复码的安全管理与多层备份策略,帮助开发者在提升账户安全的同时,享受苹果生态的无缝便捷体验。

weixin_29324401的博客 653

java await signal_【Java并发008】原理层面:ReentrantLock中 await()、signal()/signalAll()全解析...

一、前言上篇的文章中我们介绍了AQS源码中lock方法和unlock方法,这两个方法主要是用来解决并发中互斥的问题,这篇文章我们主要介绍AQS中用来解决线程同步问题的await方法、signal方法和signalAll方法,这几个方法主要对应的是synchronized中的wait方法、notify方法和notifAll方法。二、使用层面:await()与signal()/signalAll()(...

weixin_28851659的博客 1109

【Creator】cocoscreator 2.4 apk还原为工程 (1)

Cocos Creator 2.4 还原图片 meta文件

jokesuser的博客 2258

美团一面,面试官让介绍AQS原理并手写一个同步器,直接凉了

在上一篇文章中我们就已经提过了AQS是基于 模版方法模式1. 使用者继承 AbstractQueuedSynchronizer 并重写指定的方法;2. 将 AQS 组合在自定义同步组件的实现中,并调用其模板方法,而这些模板方法会调用使用者重写的方法。在模版方法模式下,有个很重要的东西,那就是“钩子方法”,这是一种抽象类中的方法,一般使用 protected 关键字修饰,可以给与默认实现,空方法居多,其内容逻辑由子类实现,为什么不适用抽象方法呢?因为,抽象方法需要子类全部实现,增加大量代码冗余!

JavaBuild的博客 848

基于云盾构建等保三级Web安全体系:从合规要求到实战落地

网络安全等级保护(等保)是保障信息系统安全的重要制度,其核心原理是通过分级防护、动态调整的策略,构建纵深防御体系。在技术层面,等保要求覆盖物理环境、通信网络、区域边界、计算环境和安全管理中心等多个层面,旨在通过技术和管理相结合的方式,有效应对网络攻击和数据泄露风险。对于Web应用而言,满足等保三级要求具有极高的技术价值,它不仅是合规的刚性需求,更是提升业务系统整体安全水位、建立用户信任、保障业务连续性的关键工程实践。在云计算时代,利用云原生安全服务(如Web应用防火墙WAF、云安全中心、态势感知等)可以高效

weixin_29324877的博客 305

SOLIDWORKS无法获得下列许可 无效的使用许可号码(-8,544,0) 解决办法大全

SOLIDWORKS无法获得下列许可 无效的使用许可号码(-8,544,0) 解决办法大全。版本:SolidWorks2021。电脑:惠普战66四代。软件安装不困难!

qq_43596278的博客 11万+

手写一个async/await的实现

众所周知,async/await只是一个语法糖,它是基于生成器来实现的,我根据网上的资料,从头开始写出它中间的原理实现。 生成器 生成器是在定义函数时在function后添加*定义的,像这样:function* func(){},执行生成器函数后会得到一个迭代器,在生成器函数中能支持yield来暂停函数,直到迭代器调用next方法.同时next能传入一个参数来作为yield的值。 这里先定义两个异步函数来作为以后的实验对象: function afunc() { return new Pr

高先生的猫 1886

端侧视觉赋能手游自动化:YOLOv8+NCNN实现低风险挂机与广告拦截

本文提出一种基于端侧AI的移动游戏自动化解决方案,采用YOLOv8目标检测和NCNN推理框架,结合AutoJS实现"感知-决策-执行"闭环。方案通过轻量化模型训练、多分辨率适配和行为拟态优化,解决了传统脚本的适配性和风控问题。关键技术包括:构建游戏专属数据集、模型量化优化、广告拦截和挂机功能实现,具有本地运行、安全稳定等特点,为个人开发者提供了一套完整的自动化开发框架。

milk416666的博客 1263

Java线程安全实战:synchronized、Lock与原子类核心原理与应用

在Java并发编程中,线程安全是保障高并发系统稳定性的核心概念,其本质在于对共享数据访问的同步控制,以防止数据竞争和不一致。从原理层面,Java主要通过锁机制和乐观锁策略实现线程安全,前者如synchronized关键字和Lock接口,通过互斥确保临界区代码串行执行;后者如原子类,基于CAS(Compare-And-Swap)操作实现无锁并发,提升性能。这些技术的工程价值在于,它们为构建可靠、高性能的分布式系统提供了基础工具。典型的应用场景包括电商库存扣减、计数器统计以及生产者-消费者模型等。本文将以一次由

352

windows 配置 libxml2

路径:\libiconv-1.9.2-1-src.zip\src\libiconv\1.9.2\libiconv-1.9.2\include\。执行完后,在当前win32目录中会生成了一个bin.msvc目录,其中就有开发需要的libxml2.lib和libxml2.dll文件。将 libiconv.la 复制到 新建的 lib 目录,并将其改名为 iconv.lib。路径:libiconv-1.9.2-1-bin.zip\lib\。将如下的 iconv.h 复制到新建的 include 目录。

SHELLCODE_8BIT的博客 3884

从基础到前沿:深度剖析光束整形与扫描技术

光束扫描的核心在于通过特定手段改变光束的传播方向,从而实现对目标区域的扫描。在这个过程中,振镜、声光偏转器、电光偏转器等元件发挥着关键作用。振镜是一种常见的光束扫描元件,它主要由电机、反射镜和透镜组成。当电机驱动反射镜旋转时,根据光的反射定律,反射镜会改变入射光线的反射方向。假设初始时光束垂直入射到反射镜上,当反射镜绕某一轴旋转一定角度时,光束的反射方向就会相应改变,从而实现光束在空间中的扫描。在激光打标设备中,通过控制振镜的快速摆动,能够使激光束在工件表面快速移动,完成各种图案和文字的标记。

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 2097

【多线程面试题 七】、 说一说Java多线程之间的通信方式

必须要注意的是,Condition 的 await()/signal()/signalAll() 使用都必须在lock保护之内,也就是说,必须在lock.lock()和lock.unlock之间才可以使用。即:Conditon中的await()对应Object的wait(),Condition中的signal()对应Object的notify(),Condition中的signalAll()对应Object的notifyAll()。反之,当一个线程被wait后,就会进入阻塞队列,等待被唤醒。

日常笔记 | 干货分享 | 毕设源码 | 毕设指导 | 答辩指导 274

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

生产者和消费者-高并发(面试题)

面试题:写一个固定容量同步容器,拥有put和get方法,以及getCount方法, 能够支持,2个生产者线程及10个消费者线程的阻塞调用(经常问!) ----------------------------------------------------------------------------- 1. 使用synchronized、wait和notify/notifyall来实现 ...

清风追梦enjoy的专栏 3231

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

复习Java,看了还不错的,资料搜集笔记

CountDownLunch(闭锁)、CyclicBarrier(栅栏锁)、Semaphore(信号量)的区别。分区只是一张表中的数据的存储位置发生改变,分表是将一张表分成多张表。分区和分表的目的都是减少数据库的负担,提高表的增删改查效率。当访问量大,且表数据比较大时,两种方式可以互相配合使用。当访问量不大,但表数据比较多时,可以只进行分区。作者不错:云扬四海(腾讯云社区)作者:HongXuan-Yuan。包含Phaser和exchange。todo 不会 字节流字符流。:如何实现按照指定顺序执行线程。

weixin_45438577的博客 1133

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

2026年Java后端面试高频考点解析与实战指南

面向对象编程作为软件开发的核心理念,通过封装、继承和多态三大特性构建模块化系统。其原理基于类与对象的关系,实现代码复用和扩展性,在Java等现代编程语言中具有重要技术价值。在实际应用场景中,集合框架通过ArrayList和HashMap等数据结构高效管理数据,JVM内存模型则优化资源分配与垃圾回收。随着分布式系统的发展,Redis分布式锁和Spring框架的IOC容器成为解决高并发问题的关键技术。本文聚焦Java基础、并发编程和JVM调优等高频面试考点,结合2026年最新趋势,帮助开发者系统掌握后端开发核心

weixin_33894640的博客 388

Java面试体系化攻略:从知识网络构建到实战场景解析

在软件工程领域,构建稳固的知识体系是工程师应对复杂挑战的基石。其核心原理在于将离散的技术点通过逻辑关联形成网络化认知,这不仅能深化对单一概念(如数据结构或并发模型)的理解,更能提升解决综合性问题的能力。这种体系化思维的技术价值在于,它使开发者能够从底层机制(如JVM内存管理)推理出高层应用表现,并高效应对高并发、分布式等真实场景。尤其在Java开发者的职业成长与面试准备中,面对海量的八股文和层出不穷的场景题,系统化的知识网络构建成为破局关键。本文聚焦于如何将Java基础、并发编程、JVM、MySQL及Spr

weixin_30243533的博客 390

Java面试核心知识点与实战技巧详解

面向对象编程(OOP)是Java语言的基石,其三大特性封装、继承和多态构成了软件开发的核心范式。封装通过隐藏实现细节和暴露可控接口来保证数据完整性,继承实现代码复用但需遵循里氏替换原则,多态则依赖JVM的虚方法表实现运行时动态绑定。在集合框架中,ArrayList与LinkedList的内存结构差异直接影响CRUD操作性能,而HashMap通过链表+红黑树解决哈希冲突,其并发版本ConcurrentHashMap采用分段锁机制保证线程安全。异常处理应遵循早抛出晚捕获原则,try-with-resources

weixin_34245749的博客 305

Java后端面试7天冲刺:HashMap、JVM、并发、MySQL、Redis、Spring核心考点精讲

如果你正在准备2026年的Java后端开发面试,并且感觉知识点太多、时间太紧、不知道从哪里开始,那么这篇文章就是为你准备的。 这不是一份简单的知识点罗列,而是一个经过验证的、可执行的“面试急救计划”。核心假设是:你只有一周左右的冲刺时间,每天能投入2-3小时。我们的目标不是成为某个领域的专家,而是在有限时间内,最高效地覆盖面试官最可能问到的核心考点,并建立清晰的回答框架。 为什么是这些主题?从近年的面试趋势看,面试官早已厌倦了死记硬背的“八股文”。他们更倾向于通过 HashMap、JVM、并发编程 这些“经

weixin_33770878的博客 336

Java高并发与多线程面试核心:从JMM原理到秒杀系统设计实战

并发编程是构建高性能、高可用软件系统的核心技术基础,其核心在于解决多线程环境下对共享资源的安全访问与协调问题。从原理层面,Java内存模型(JMM)通过定义主内存与工作内存的交互规则,以及happens-before原则,为并发操作提供了可见性与有序性的理论保障。在工程实践中,开发者需要掌握线程安全、锁机制(如synchronized与ReentrantLock)、原子变量(CAS)以及并发容器等核心工具,以应对数据竞争、死锁等经典并发问题。这些技术的价值在于能够有效提升系统吞吐量、降低响应延迟,是构建电商

weixin_34239169的博客 334

【面试】搞定面试就这么简单!!!

参数化类型”,类型由具体的类型参数化,把类型也定义成参数形式(称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。泛型的本质是把参数的类型参数化,也就是所操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中。使用泛型编写的程序代码,要比使用 Object 变量再进行强制类型转换的代码,具有更好的安全性和可读性。多种数据类型执行相同的代码使用泛型可以复用代码// 定义一个泛型方法,用于打印数组元素// 创建一个 Integer 数组。

fearless的博客 770

Java开发八股准备V1.1

反射是一种在程序运行阶段,动态获取类和执行方法的能力,该方法突破了Java编译时确定类型的限制,为动态编程提供了底层支持,很多主流框架。

写代码的小阿帆的博客 217
上一篇: 面试锦集:手写一个同步类容器之wait/notify/notifyAll实现
下一篇: JAVA多线程高并发之ReentrantLock讲解lock/unlock/tryLock方法
饶艳辉
博客等级 码龄15年 20粉丝 46原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值