CompletableFuture 详解 Future类是异步思想的典型运用,主要用在一些需要执行耗时任务的场景,避免程序一直原地等待耗时任务执行完成,执行效率太低。具体来说是这样的:当我们执行某一耗时的任务时,可以将这个耗时任务交给一个子线程去异步执行,同时我们可以干点其他事情,不用傻傻等待耗时任务执行完成。等我们的事情干完后,我们再通过Future类获取到耗时任务的执行结果。这样一来,程序的执行效率就明显提高了这其实就是多线程中经典的Future 模式。
AQS 介绍 使用者继承并重写指定的方法将 AQS 组合在自定义同步组件的实现中,并调用其模板方法,而这些模板方法会调用使用者重写的方法这和我们以往通过实现接口的方式有很大区别,这是模板方法模式很经典的一个运用//独占方式。尝试获取资源,成功则返回true,失败则返回false。//独占方式。尝试释放资源,成功则返回true,失败则返回false。//共享方式。尝试获取资源。负数表示失败;0表示成功,但没有剩余可用资源;正数表示成功,且有剩余资源。//共享方式。
Atomic 原子类介绍 Atomic翻译成中文是“原子”的意思。在化学上,原子是构成物质的最小单位,在化学反应中不可分割。在编程中,Atomic指的是一个操作具有原子性,即该操作不可分割、不可中断。即使在多个线程同时执行时,该操作要么全部执行完成,要么不执行,不会被其他线程看到部分完成的状态。原子类简单来说就是具有原子性操作特征的类包中的Atomic原子类提供了一种线程安全的方式来操作单个变量Atomic类依赖于 CAS(Compare-And-Swap,比较并交换)乐观锁来保证其方法的原子性,而不需要使用传统的锁机制(如块或。
Java 常见并发容器 上面我们己经提到了作为高性能的非阻塞队列。下面我们要讲到的是阻塞队列——。阻塞队列()被广泛使用在“生产者-消费者”问题中,其原因是提供了可阻塞的插入和移除的方法。当队列容器已满,生产者线程会被阻塞,直到队列未满;当队列容器为空时,消费者线程会被阻塞,直至队列非空时为止是一个接口,继承自Queue,所以其实现类也可以作为Queue的实现来使用,而Queue又继承自Collection接口。下面是的相关实现类:下面主要介绍一下 3 个常见的。
JMM内存模型详解 Java 是最早尝试提供内存模型的编程语言。由于早期内存模型存在一些缺陷(比如非常容易削弱编译器的优化能力),从 Java5 开始,Java 开始使用新的内存模型一般来说,编程语言也可以直接复用操作系统层面的内存模型。不过,不同的操作系统内存模型不同。如果直接复用操作系统层面的内存模型,就可能会导致同样一套代码换了一个操作系统就无法执行了。Java 语言是跨平台的,它需要自己提供一套内存模型以屏蔽系统差异这只是 JMM 存在的其中一个原因。
Java并发常见面试题总结(下) 顾名思义,线程池就是管理一系列线程的资源池。当有任务要处理时,直接从线程池中获取线程来处理,处理完之后线程并不会立即被销毁,而是等待下一个任务默认使用全局共享的作为执行器,所有未指定执行器的异步任务都会使用该线程池。
乐观锁、悲观锁简介 悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程像 Java 中和等独占锁就是悲观锁思想的实现// 需要同步的操作try {// 需要同步的操作高并发的场景下,激烈的锁竞争会造成线程阻塞,大量阻塞线程会导致系统的上下文切换,增加系统的性能开销。
Java并发常见面试题总结(中) 悲观锁总是假设最坏的情况,认为共享资源每次被访问的时候就会出现问题(比如共享数据被修改),所以每次在获取资源操作的时候都会上锁,这样其他线程想拿到这个资源就会阻塞直到锁被上一个持有者释放。也就是说,共享资源每次只给一个线程使用,其它线程阻塞,用完后再把资源转让给其它线程。像 Java 中和等独占锁就是悲观锁思想的实现// 需要同步的操作try {// 需要同步的操作高并发的场景下,激烈的锁竞争会造成线程阻塞,大量阻塞线程会导致系统的上下文切换,增加系统的性能开销。
Java集合 Map 常见面试题总结 为了让HashMap存取高效并减少碰撞,我们需要确保数据尽量均匀分布。哈希值在 Java 中通常使用int表示,其范围是前后加起来大概 40 亿的映射空间,只要哈希函数映射得比较均匀松散,一般应用是很难出现碰撞的。但是,问题是一个 40 亿长度的数组,内存是放不下的。所以,这个散列值是不能直接拿来用的。用之前还要先做对数组的长度取模运算,得到的余数才能用来要存放的位置也就是对应的数组下标这个算法应该如何设计呢?我们首先可能会想到采用 % 取余的操作来实现。但是,重点来了:“
Java并发常见面试题总结(上) 程序计数器主要有下面两个作用:字节码解释器通过改变程序计数器来依次读取指令,从而实现代码的流程控制,如:顺序执行、选择、循环、异常处理在多线程的情况下,程序计数器用于记录当前线程执行的位置,从而当线程被切换回来的时候能够知道该线程上次运行到哪儿了如果执行的是 native 方法,那么程序计数器记录的是 undefined 地址,只有执行的是 Java 代码时程序计数器记录的才是下一条指令的地址所以,程序计数器私有主要是为了线程切换后能恢复到正确的执行位置。
NIO 核心知识总结 在传统的 Java I/O 模型(BIO)中,I/O 操作是以阻塞的方式进行的。也就是说,当一个线程执行一个 I/O 操作时,它会被阻塞直到操作完成。这种阻塞模型在处理多个并发连接时可能会导致性能瓶颈,因为需要为每个连接创建一个线程,而线程的创建和切换都是有开销的为了解决这个问题,在 Java1.4 版本引入了一种新的 I/O 模型 —(New IO,也称为 Non-blocking IO)。
I/O 模型 像我们平常运行的应用程序都是运行在用户空间,只有内核空间才能进行系统态级别的资源有关的操作,比如文件管理、进程通信、内存管理等等。但是,当面对十万甚至百万级连接的时候,传统的 BIO 模型是无能为力的。同步非阻塞 IO 模型中,应用程序会一直发起 read 调用,等待数据从内核空间拷贝到用户空间的这段时间里,线程依然是阻塞的,直到在内核把数据拷贝到用户空间。异步 IO 是基于事件和回调机制实现的,也就是应用操作之后会直接返回,不会堵塞在那里,当后台处理完成,操作系统会通知相应的线程进行后续的操作。
IO 设计模式 IO 流中的字符流和字节流的接口不同,它们之间可以协调工作就是基于适配器模式来做的,更准确点来说是对象适配器。更侧重于让接口不兼容而不能交互的类可以一起工作,当我们调用适配器对应的方法时,适配器内部会调用适配者类或者和适配类相关的类的方法,这个过程透明的。更侧重于动态地增强原始类的功能,装饰器类需要跟原始类继承相同的抽象类或者实现相同的接口。装饰器模式通过组合替代继承来扩展原始类的功能,在一些继承关系比较复杂的场景(IO 这一场景各种类的继承关系就比较复杂)更加实用。的子类比较少的话,这样做是没问题的。
Shiro 会话管理和加密 为了提高安全性,Shiro 支持加盐(Salt)机制,即在明文密码基础上加一段随机字符串(盐),再进行哈希运算。负责会话的持久化与读取,它支持将会话信息存储到不同介质中(如内存、数据库、文件或分布式缓存)。在验证用户登录时,Shiro 可以将用户输入的密码进行相同的加密操作,然后与数据库中的加密结果进行比较。接口提供了基础会话操作,如获取或设置会话属性、会话ID、超时时间等。Shiro 提供了丰富的会话管理接口以支持与 Web 环境无关的会话操作。方法可以获取当前用户的会话,支持自动创建或获取已有会话。
IO 流详解 IO 即,输入和输出。数据输入到计算机内存的过程即输入,反之输出到外部存储(比如数据库,文件,远程主机)的过程即输出。数据传输过程类似于水流,因此称为 IO 流。IO 流在 Java 中分为输入流和输出流,而根据数据的处理方式又分为字节流和字符流。Java IO 流的 40 多个类都是从如下 4 个抽象类基类中派生出来的。Reader: 所有的输入流的基类,前者是字节输入流,后者是字符输入流Writer: 所有输出流的基类,前者是字节输出流,后者是字符输出流。
DelayQueue 简介 DelayQueue是 JUC 包(为我们提供的延迟队列,用于实现延时任务比如订单下单 15 分钟未支付直接取消。它是的一种,底层是一个基于实现的一个无界队列,是线程安全的DelayQueue中存放的元素必须实现Delayed接口,并且需要重写getDelay()方法(计算是否到期)默认情况下,DelayQueue会按照到期时间升序编排任务。只有当元素过期时(getDelay()方法返回值小于等于 0),才能从队列中取出。
ArrayBlockingQueue 源码分析 Java 阻塞队列的历史可以追溯到 JDK1.5 版本,当时 Java 平台增加了,即我们常说的 JUC 包,其中包含了各种并发流程控制工具、并发容器、原子类等。这其中自然也包含了我们这篇文章所讨论的阻塞队列为了解决高并发场景下多线程之间数据共享的问题,JDK1.5 版本中出现了和,它们是带有生产者-消费者模式实现的并发容器。其中,是有界队列,即添加的元素达到上限之后,再次添加就会被阻塞或者抛出异常。而则由链表构成的队列,正是因为链表的特性,所以在添加元素上并不会向那样有着较多的约束,所以。
CopyOnWriteArrayList详解 在 JDK1.5 之前,如果想要使用并发安全的List只能选择Vector。而Vector是一种老旧的集合,已经被淘汰。Vector对于增删改查等方法基本都加了,这种方式虽然能够保证同步,但这相当于对整个Vector加上了一把大锁,使得每个方法执行的时候都要去获得锁,导致性能非常低下JDK1.5 引入了(JUC)包,其中提供了很多线程安全且并发性能良好的容器,其中唯一的线程安全List实现就是。
Shiro授权详解 在进行Shiro授权之前,了解相关术语对于理解整个过程至关重要。Shiro的授权机制以角色为中心,辅以权限,来控制主体对资源的访问。授权是指确定主体是否有权访问某一资源或执行某一操作。通过角色和权限机制,Shiro为系统提供了细粒度的访问控制能力主体是指当前的用户、设备或其他能与应用进行交互的实体。每个主体在登录后,会被分配一定的权限和角色来确定其行为资源可以是系统中的任意数据或服务,例如文件、API接口等,主体通过权限来访问这些资源权限是允许主体执行某个具体操作的规则。