JAVA面试系列-多线程和java锁

线程池的三大方法、七大参数、四种拒绝策略

三大方法:在Executor方法类中,可以看到有三个方法,分别是
ExecutorService threadPool = Executors.newSingleThreadExecutor();// 单个线程
ExecutorService threadPool = Executors.newFixedThreadPool(5); // 创建一个固定的线程池的大小
ExecutorService threadPool = Executors.newCachedThreadPool(); // 可伸缩的,遇强则强,遇弱则弱
七大参数:查看三个方法的底层源码得知看,它们底层都是调用ThreadPoolExecutor()方法实现的,其有7个参数

// 本质ThreadPoolExecutor()
public ThreadPoolExecutor(int corePoolSize, // 核心线程池大小
int maximumPoolSize, // 最大核心线程池大小
long keepAliveTime, // 超时了没有人调用就会释放
TimeUnit unit, // 超时单位
BlockingQueue<Runnable> workQueue, // 阻塞队列
ThreadFactory threadFactory, // 线程工厂:创建线程的,一般不用动
RejectedExecutionHandler handle // 拒绝策略) 

拿银行举个例子,银行办理业务,假设有1-5一共5个柜台,正常情况下就只有1和2两个柜台开放,候客区有三个位置,但是有一天,人特别多,1和2两个柜台和
在这里插入图片描述

四种拒绝策略:
在这里插入图片描述

/**
* new ThreadPoolExecutor.AbortPolicy() // 银行满了,还有人进来,不处理这个人的,抛出异
常
* new ThreadPoolExecutor.CallerRunsPolicy() // 哪来的去哪里!
* new ThreadPoolExecutor.DiscardPolicy() //队列满了,丢掉任务,不会抛出异常!
* new ThreadPoolExecutor.DiscardOldestPolicy() //队列满了,尝试去和最早的竞争,也不会
抛出异常!
*/

2.最大线程数如何定义?(从CPU密集型和IO密集型考虑)

// 最大线程到底该如何定义
// 1、CPU 密集型,几核,就是几,可以保持CPu的效率最高!
// 2、IO 密集型 > 判断你程序中十分耗IO的线程,
// 程序 15个大型任务 io十分占用资源!

3.线程池的五种状态

Running、Shutdown、Stop、Tidying、Terminated

4.线程池的任务执行流程、excute方法和 submit方法的区别

  • execute只能提交Runnable类型的任务,无返回值。submit既可以提交Runnable类型的任务,也可以提交Callable类型的任务,会有一个类型为Future的返回值,但当任务类型为Runnable时,返回值为null。
  • execute在执行任务时,如果遇到异常会直接抛出,而submit不会直接抛出,只有在使用Future的get方法获取返回值时,才会抛出异常。

5.Synchronized锁和Lock锁的区别\

1、Synchronized 内置的Java关键字, Lock 是一个Java类
2、Synchronized 无法判断获取锁的状态,Lock 可以判断是否获取到了锁
3、Synchronized 会自动释放锁,lock 必须要手动释放锁!如果不释放锁,死锁
4、Synchronized 线程 1(获得锁,阻塞)、线程2(等待,傻傻的等);Lock锁就不一定会等待下去;
5、Synchronized 可重入锁,不可以中断的,非公平;Lock ,可重入锁,可以 判断锁,非公平(可以
自己设置);
6、Synchronized 适合锁少量的代码同步问题,Lock 适合锁大量的同步代码!、

6.wait和sleep的区别

1、来自不同的类
wait => Object
sleep => Thread
2、关于锁的释放
wait 会释放锁,sleep 睡觉了,抱着锁睡觉,不会释放!
3、使用的范围是不同的
wait在同步代码块中,sleep可以在任何地方
4、是否需要捕获异常
wait 不需要捕获异常
sleep 必须要捕获异常

7.Java线程虚假唤醒

线程本应该处于wait状态却被唤醒了,解决方案是wait方法应该用while循环包裹,不用if

8.JMM的三种特性(原子性、可见性、有序性)、主内存和线程工作内存的八种交互动作

  • lock (锁定):作用于主内存的变量,把一个变量标识为线程独占状态
  • unlock (解锁):作用于主内存的变量,它把一个处于锁定状态的变量释放出来,释放后的变量才可以被其他线程锁定
  • read (读取):作用于主内存变量,它把一个变量的值从主内存传输到线程的工作内存中,以便随后的load动作使用
  • load (载入):作用于工作内存的变量,它把read操作从主存中变量放入工作内存中
  • use (使用):作用于工作内存中的变量,它把工作内存中的变量传输给执行引擎,每当虚拟机遇到一个需要使用到变量的值,就会使用到这个指令
  • assign (赋值):作用于工作内存中的变量,它把一个从执行引擎中接受到的值放入工作内存的变
    量副本中
  • store (存储):作用于主内存中的变量,它把一个从工作内存中一个变量的值传送到主内存中,以便后续的write使用
  • write (写入):作用于主内存中的变量,它把store操作从工作内存中得到的变量的值放入主内
    存的变量中

9.volatile如何保证可见性(MESI缓存一致性协议)

10.volatile如何保证有序性(内存屏障——lock前缀指令)

11.synchronized和volatile的区别

  • 使用上的区别
    volatile只能修饰变量,synchronized只能修饰方法和语句块;
  • 对原子性的保证
    synchronized可以保证原子性,volatile不能保证原子性;
  • 对可见性的保证
    都可以保证可见性,但实现原理不同,volatile对变量加了lock,synchronized使用monitorEnter和monitorExit;
  • 对有序性的保证
    都可以保证有序性,但是synchronized并发退化到串行;
  • 其他
    synchronized引起阻塞;volatile不会引起阻塞;

12.JUC包中的原子类如何保证原子性

CAS 操作包含三个操作数 —— 内存位置(V)、预期原值(A)和新值(B)。 如果内存位置的值与预期原值相匹配,那么处理器会自动将该位置值更新为新值,当内存值和预期值不相同时,自旋锁会一直自旋,一直处于阻塞状态。

13.CAS机制,会引发什么问题,如何解决ABA问题

CAS会导致ABA问题,解决ABA问题是使用版本号机制

14.悲观锁和乐观锁的区别,应用?(java中的Synchronized关键字和lock锁使用的都是悲观锁;CAS机制是乐观锁的一种实现方式)>

15.公平锁和非公平锁(公平锁按照先来先服务,不会出现饥饿;非公平锁会导致饥饿,但是效率更高,默认的锁都是非公平的)

16.自旋锁和互斥锁,自旋锁的优缺点

自旋锁与互斥锁有点类似,只是自旋锁不会引起调用者睡眠,如果自旋锁已经被别的执行单元保持,调用者就一直循环在那里看是 否该自旋锁的保持者已经释放了锁,"自旋"一词就是因此而得名。其作用是为了解决某项资源的互斥使用。因为自旋锁不会引起调用者睡眠,所以自旋锁的效率远 高于互斥锁。虽然它的效率比互斥锁高,但是它也有些不足之处:

  • 自旋锁一直占用CPU,他在未获得锁的情况下,一直运行--自旋,所以占用着CPU,如果不能在很短的时 间内获得锁,这无疑会使CPU效率降低。

两种锁的加锁原理:

在用自旋锁时有可能造成死锁,当递归调用时有可能造成死锁,调用有些其他函数也可能造成死锁,如 copy_to_user()、copy_from_user()、kmalloc()等。
互斥锁:线程会从sleep(加锁)——>running(解锁),过程中有上下文的切换,cpu的抢占,信号的发送等开销。

自旋锁:线程一直是running(加锁——>解锁),死循环检测锁的标志位,机制不复杂。

17.Synchronized锁的底层实现,锁的是什么,其它线程如何判断该锁已经被占用了

基于监视器monitor对象实现,javap反编译可看到有monitorenter监视入口 和monitorexit监视器出口

18.死锁产生的四个必要条件以及死锁的处理策略

死锁是指两个或两个以上的进程(线程)在运行过程中因争夺资源而造成的一种僵局(Deadly-Embrace) ) ,若无外力作用,这些进程(线程)都将无法向前推进。
四个条件:互斥条件,不可剥夺条件,请求保持条件,循环等待条件
处理策略:预防,避免,检测,解除
银行家算法:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值