面试题-并发
文章平均质量分 76
桃月十二_
这个作者很懒,什么都没留下…
展开
-
线程池的拒绝策略
当线程池的线程数达到最大线程数时,需要执行拒绝策略。例如,某些视频网站统计视频的播放量就是采用的这种拒绝策略。如果是比较关键的业务,推荐使用此拒绝策略,这样子在系统不能承载更大的并发量的时候,能够及时的通过异常发现。丢弃任务,但是不抛出异常。如果线程队列已满,则后续提交的任务都会被丢弃,且是静默丢弃。这是线程池默认的拒绝策略,在任务不能再提交的时候,抛出异常,及时反馈程序运行状态。如果任务被拒绝了,则由调用线程(提交任务的线程)直接执行此任务。丢弃队列最前面的任务,然后重新提交被拒绝的任务。转载 2023-04-28 16:39:14 · 136 阅读 · 0 评论 -
synchronized锁应用场景
虽然是通过对象访问的此方法,但是加锁的代码块是类级别的跨对象的,所以锁的范围是针对类,多个线程访问互斥。普通方法作用范围是对象实例,不可跨对象,所以多个线程不同对象实例访问此方法,互不影响,无法产生互斥。作用范围是对象实例,不可跨对象,所以多个线程不同对象实例访问此方法,互不影响,无法产生互斥。静态方法是通过类访问,是类级别的跨对象的,所以锁的范围是针对类,多个线程访问互斥。原创 2023-03-30 15:38:38 · 122 阅读 · 0 评论 -
重量级锁的8连问
如果使用一个队列冲突的概率会加大,耗费系统资源。默认情况下,线程进入重量级锁的抢锁阶段,第一步就会尝试通过自旋来抢锁,所以默认相当于AQS中的非公平锁。即使自旋时未抢到锁,按照上面讲的cxq出入队逻辑,也是后进先出,正常情况下后进入等待队列的线程会先抢到锁,这一点也是和AQS中相反的。1)如果是notify,唤醒的是waitset的队首节点,如果这时候EntryList不为空,则放入EntryList,否则放入cxq。因为是cxq后进先出,所以被唤醒的线程比等待队列中的线程先出队,会先抢到锁。转载 2023-03-22 10:28:56 · 136 阅读 · 0 评论 -
synchronized保证可见性、有序性、原子性
monitorenter、monitorexit这两条指令其实就相当于复合指令,既具有加锁、释放锁的功能,同时也具有内存屏障的功能。这样通过这种方式,数据修改之后立即刷新回主内存,其他线程进入synchronized代码块后,使用共享变量的时候强制读取主内存的数据,上一个线程对共享变量的变更操作,它就能立即看到了。也就是通过monitorenter指令之后,synchronized内部的共享变量,每次读取数据的时候被强制从主内存读取最新的数据。monitorexit指令也具有Store屏障的作用。转载 2023-02-10 16:21:28 · 200 阅读 · 0 评论 -
synchronized的锁重入、锁消除、锁升级原理
总的来说啊,JVM设计的这套synchronized锁升级的原则,主要是为了花费最小的代价能达到加锁的目的;比如在没有竞争的情况下,进入synchronized的使用使用偏向锁就够了,这样只需要第一次执行CAS操作获取锁,获取了偏向锁之后,后面每次进入synchronized同步代码块就不需要再次加锁了。然后在存在多个线程竞争锁的时候就不能使用偏向锁了,不能只偏心一个人,它优先获取锁,别人都看它表演,这样是不行的。于是就升级为轻量级锁,在轻量级锁模式在每次加锁和释放是都需要执行CAS操作。转载 2023-02-10 16:15:04 · 507 阅读 · 0 评论 -
synchronized底层到底是怎么加锁的
monitor叫做对象监视器、也叫作监视器锁,JVM规定了每一个java对象都有一个monitor对象与之对应,这monitor是JVM帮我们创建的,在底层使用C++实现的。_header;_count;// 非常重要,表示锁计数器,_count = 0表示还没人加锁,_count > 0 表示加锁的次数 _waiters;_owner;// 非常重要,指向加锁成功的线程,_owner = null 时候表示没人加锁 _waitset;转载 2023-02-10 15:55:42 · 354 阅读 · 0 评论 -
基础篇(三):CPU多级缓存模型 / MESI缓存一致性协议
CPU与主存运行速度的差异,导致CPU长时间空闲。CPU是计算机的大脑,是负责执行指令的;自身的频率和指令执行的速度非常快,一秒执行的指令大概10^9级别的;内存的的速度要比CPU慢上好几个级别,每秒处理的速度大概是10^6的级别的。这样就会导致一个问题;如果CPU要频繁的访问主存的话,每次都需要等待很长的时间,执行性能就会低,大部分时间都在等待主存返回数据,没有发挥出CPU的性能。转载 2023-02-09 20:38:10 · 608 阅读 · 0 评论 -
基础篇(一):Java内存模型
lock(锁定):把主内存中的一个共享变量标记为一个线程独享的状态unlock(解锁):把主内存的变量从线程独享的lock状态中解除出来read(读取):把主内存的一个共享变量传输工作内存中load(载入):把从主内存传输到工作内存的共享变量,赋值给工作内存中的变量副本use(使用):把工作内存中的变量副本的值,传递给执行引擎CPUassign(赋值):执行引擎(CPU)执行完之后,把修改过的变量值重新赋值给工作内存中的变量副本。转载 2023-02-09 20:08:21 · 67 阅读 · 0 评论 -
基础篇(二):内存屏障是什么
内存屏障是一种指令,无论是在JAVA内存模型还是CPU层次,都是有具体的指令对应的,是一种特殊的指令。只要加了Load屏障,相当于加了一个栅栏,不管工作内存是否有数据,都是从主内存读取数据。只要加了Store屏障,具有强制作用,进行assign操作将变量更改了之后,立刻将变量刷新到主内存。转载 2023-02-09 19:31:12 · 1302 阅读 · 0 评论 -
为什么说synchronized是重量级锁
Synchronized 底层是依赖于操作系统的 mutex lock 指令实现的,锁的状态是由内核来维护的,也就是说每次尝试获取锁的时候都需要先挂起线程切换到内核态,然后由内核去做协调,然后去阻塞or唤醒线程。值得注意的是:尽管 ReentrantLock 不需要切换到内核去维护锁状态,但是在线程需要阻塞的情况下,内核态/用户态的切换还是无法避免的(线程的唤醒和挂起依旧是需要由内核进行的)首先需要理解的是,当锁被占用的时候,Synchronized和ReentrantLock的区别是不大的。原创 2022-11-07 21:00:36 · 530 阅读 · 0 评论 -
AQS解读 -- 独占模式(ReentrantLock)
它将请求共享资源的线程封装成队列的结点(Node) ,通过CAS自旋以及LockSuport.park()的方式,维护state变量的状态,使并发达到同步的效果。CONDITION(-2):Condition中使用,当前线程阻塞在Condition,如果其他线程调用了Condition的signal方法,这个结点将从等待队列转移到同步队列队尾,等待获取同步锁;CLH:通过内置的CLH(FIFO)队列的变种来完成资源获取线程的排队工作,将每条将要去抢占资源的线程封装成一个Node节点来实现锁的分配。原创 2022-11-03 20:32:40 · 257 阅读 · 0 评论 -
synchronized(string)
String是Java中的一种特殊类型,String在创建后存入字符串常量池。利用这个特征,可以使用String作为同步锁。例如,在更新用户信息时,可以使用用户的名称作为同步锁,不同的用户可以使用不同的锁来提高并发性能。这个特征扩展适当的场景非常多。原创 2022-11-02 17:08:51 · 1964 阅读 · 0 评论 -
CompletableFuture API
}原创 2022-10-29 18:00:34 · 694 阅读 · 0 评论 -
Future API
当我们提交一个Callable任务后,我们会同时获得一个Future对象,然后,我们在主线程某个时刻调用Future对象的get()方法,就可以获得异步执行的结果。在调用get()时,如果异步任务已经完成,我们就直接获得结果。如果异步任务还没有完成,那么get()会阻塞,直到任务完成后才返回结果。ExecutorService.submit()方法,返回了一个Future类型,一个Future类型的实例代表一个未来能获取结果的对象。isDone():判断任务是否已完成。get():获取结果(可能会等待)原创 2022-10-29 17:47:48 · 337 阅读 · 0 评论 -
多线程面试题 --- ForkJoin
一个大任务拆分成多个小任务,为了减少线程间的竞争,把这些子任务分别放到不同的队列中,并且每个队列都有单独的线程来执行队列里的任务,线程和队列一一对应。但是会出现这样一种情况:A线程处理完了自己队列的任务,B线程的队列里还有很多任务要处理。A是一个很热情的线程,想过去帮忙,但是如果两个线程访问同一个队列,会产生竞争,所以A想了一个办法,从双端队列的尾部拿任务执行。而B线程永远是从双端队列的头部拿任务执行。原创 2021-04-03 21:42:03 · 431 阅读 · 0 评论 -
java中Future的使用
submit需要接受一个Callable参数,Callable需要实现一个call方法,并返回结果。如果在等待时间结束的时候,Future还有返回,则会抛出一个TimeoutException。一般来说,当我们执行一个长时间运行的任务时,使用Future就可以让我们暂时去处理其他的任务,等长任务执行完毕再返回其结果。Future代表的是异步执行的结果,意思是当异步执行结束之后,返回的结果将会保存在Future中。这里futureOne.get()是一个阻塞操作,会一直等待异步执行完毕才返回结果。转载 2022-10-24 09:50:04 · 1130 阅读 · 0 评论 -
【面试题】AQS -- 共享模式
只有一个线程能执行,如 ReentrantLock。原创 2022-09-20 17:10:53 · 918 阅读 · 0 评论 -
【面试题】线程池
3.keepAliveTime,多余存活线程的存活时间,当线程池中线程数超出corePoolSize,当空闲时间超出keepAliveTime,多余线程会销毁直到只剩下corePoolSize个核心线程.IO密集型(任务线程并不是一直在执行任务,则应尽可能多的配置线程):CPU核数 * 2。按着下面线程池原理图写的,核心线程:2,最大线程:5,队列长度:3,默认的拒绝策略。2.maximumPoolSize,线程池中可同时执行的最大线程数。1.corePoolSize,线程池中常驻核心线程数.原创 2022-09-02 16:57:50 · 731 阅读 · 0 评论 -
【面试题】LockSupport
LockSupport是一个线程工具类,主要是为了park()阻塞线程,unpark()唤醒线程的时候使用。原创 2022-09-06 22:34:52 · 150 阅读 · 0 评论 -
【面试题】死锁
【代码】【面试题】死锁。原创 2022-09-02 19:16:40 · 257 阅读 · 0 评论 -
【面试题】Callable使用
【代码】【面试题】Callable使用。原创 2022-09-02 14:56:07 · 110 阅读 · 0 评论 -
【面试题】synchronized和lock的区别、手写生产者消费者
等待是否可中断synchronized不可被中断,除非抛出异常或者方法正常执行结束。ReentrantLock可以被中断,1. 设置超时方法,;2.中断绑定多个conditionsychronized没有。(要么随机唤醒一个要么全部唤醒)ReentrantLock可以实现精准唤醒。1.2 condition精准唤醒demo一共3个线程,线程A打印数字1,线程2打印数字1,2,线程3打印数据1,2,3,轮询10次。原创 2022-09-02 13:47:14 · 153 阅读 · 0 评论 -
【面试题】自旋锁、读写锁
独占锁:锁一次只能被一个线程持有。(ReentrantLock、synchronized都是独占锁)尝试获取锁的线程如果没有获得锁,不会立即阻塞,而是利用循环的方式继续获得锁。ReentrantReadWriteLock读锁是共享锁,写锁是独占锁。使用ReentrantReadWriteLock。读锁的共享锁可以保证并发读,读写,写写都互斥。共享锁:锁可以被多个线程持有。写锁是独占锁,读锁是共享锁。减少上下文切换的消耗。...原创 2022-09-01 16:23:06 · 183 阅读 · 0 评论 -
【面试题】公平锁和非公平锁、可重入锁
公平锁,在并发环境中,每个线程获取锁的时候会优先查询此锁维护的等待队列,如果为空或者自己是等待队列的第一个直接占有锁,否则加入等待队列。同一线程,在外层方法获取锁后,内层方法自动获取锁。也就是说,线程可以进入任何一个他已经拥有锁同步的方法。多个线程并非按着申请锁的顺序来获取锁,有可能后申请的线程更早获得锁,有可能会造成优先级反转。非公平锁,上来就尝试占有锁,如果尝试失败,再采用类似公平锁的方式。多个线程按着申请锁的顺序来获取锁(类似排队,先来后到)。......原创 2022-09-01 14:50:25 · 264 阅读 · 0 评论 -
【面试题】集合并发问题 CopyOnWriteArrayList(读写分离思想)
暂无原创 2022-08-30 17:10:56 · 354 阅读 · 0 评论 -
ThreadLocal内存泄露
内存泄露相关概念内存溢出:没有足够的内存供提供者使用。内存泄漏:指程序中已经动态分配的内存由于各种原因程序未释放或者无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果,内存泄漏的堆积最终导致内存溢出。引用类型java中一共有4种引用类型,强,软,弱,虚。当前这个问题主要涉及到强引用和弱引用。强引用:就是我们常见的普通对象引用,只要还有强引用指向一个对象,就能表示这个对象还活着,垃圾回收器就不会回收这种对象。弱引用:垃圾回收器一旦发现了只具有弱引用的对象,不管当前内存是否足够原创 2021-04-28 15:51:40 · 156 阅读 · 0 评论 -
ThreadLocal原理分析&&面试题
ThreadLocal提供线程内的局部变量,不同的线程之间不会相互干扰,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或组件之间一些公共变量传递的复杂度。ThreadLocal Api方法声明描述ThreadLocal()创建ThreadLocal对象public void set( T value)设置当前线程绑定的局部变量public T get()获取当前线程绑定的局部变量public void remove()移除当前线程绑定的局部变原创 2021-04-27 11:27:07 · 210 阅读 · 0 评论 -
【面试题】sychronized
Synchronized是一个同步关键字,在某些多线程场景下,如果不进行同步会导致数据不安全,而Synchronized关键字就是用于代码同步。什么情况下会数据不安全呢,要满足两个条件:一是数据共享(临界资源),二是多线程同时访问并改变该数据。修饰静态方法(锁当前类):对当前类的Class对象加锁修饰实例方法(锁当前对象实例):对当前实例对象this加锁修饰代码块(锁指定对象/类):synchronized(object) 表示进入同步代码库前要获得 给定对象的锁。synchronized(类.cla原创 2022-09-03 14:34:35 · 545 阅读 · 0 评论 -
【面试题】volatile关键字、单例模式(DCL)
volatile关键字原创 2022-08-30 10:32:09 · 439 阅读 · 0 评论 -
【面试题】多线程 - 基础
实现多线程的方法线程和进程线程状态Synchronized锁Lock锁0.实现多线程的方法1.继承Thread类2.实现Runnable接口(无返回值)3.实现Callable接口 (有返回值)1.线程和进程进程:一个程序,QQ.exe Music.exe 等线程:进程的最小执行单位一个进程往往可以包含多个线程,至少包含一个!问题:Java 真的可以开启线程吗?答: 不可以!!!new Thread().start();public synchronized v.原创 2021-04-03 12:35:17 · 159 阅读 · 0 评论