java多线程模块

java多线程复习

1 并行和并发有什么区别?

并行:多个处理器或多核处理器同时处理多个任务。(两个饮水机两个人接水)
并发:多个任务在同一个 CPU 核上,按细分的时间片轮流(交替)执行,从逻辑上来看那些任务是同时执行。(一个饮水机多个人接水)

2 线程和进程的区别?

一个程序下至少有一个进程,一个进程下至少有一个线程,一个进程下也可以有多个线程同时工作来增加程序的执行速度

3 守护线程是什么?

守护线程是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。在 Java 中垃圾回收线程就是特殊的守护线程。

4 多线程有几种实现方式?

-1继承Thread类
-2实现Runnable接口
-3实现Callable接口通过FutureTask包装器来创建Thread线程
-4通过线程池创建线程,使用线程池接口ExecutorService结合Callable、Future实现有返回结果的多线程。
前面两种无返回值:因为通过重写tun()来实现线程,run()本身没有返回值,所以重写后也无返回值
后面两种有返回值:因为痛过Callable接口实现线程,需要实现call(),因为call()返回值为Object,所以返回的结果可以放在Object对象中

5 说一下 Runnable和 Callable有什么区别

Runnable无返回值,Callable有返回值,Callable可以看做是对前者的补充

6 线程有哪些状态?

新建状态/可运行状态/运行状态/阻塞状态/死亡状态

7 sleep() 和 wait() 有什么区别?

所属类不同:sleep()来自于Rhread类,wait()来自于Object类
是否释放锁:sleep()不释放锁,wait会释放锁
用法不用:sleep()时间到了会自动恢复,而wait()需要notify()/notifyAll()方法来唤醒

8 notify()和 notifyAll()有什么区别?

notify()只能唤醒一个线程,唤醒哪一个线程由虚拟机决定
notifyAll()会唤醒所有的线程,notifyAll()调用后,会将所有线程移到锁池,这些线程来参与锁的竞争,竞争成功则可以继续执行,如果竞争不成功则会留在锁池,等待锁被释放,参与下一轮的竞争.

9 线程的 run() 和 start() 有什么区别?

run()可以重复使用,而start()只能调用一次
run()用于执行线程运行时的代码,而start()用于启动线程

10 创建线程池有哪几种方式?############不太会

七种:
newSingleThreadExecutor():它的特点在于工作线程数目被限制为 1,操作一个无界的工作队列,所以它保证了所有任务的都是被顺序执行,最多会有一个任务处于活动状态,并且不允许使用者改动线程池实例,因此可以避免其改变线程数目
newCachedThreadPool():它是一种用来处理大量短时间工作任务的线程池,具有几个鲜明特点:它会试图缓存线程并重用,当无缓存线程可用时,就会创建新的工作线程;如果线程闲置的时间超过60秒,则被终止并移出缓存;长时间闲置时,这种线程池,不会消耗什么资源.其内部使用SynchronousQueue作为工作队列;
newFixedThreadPool(int nThreads):重用指定数目(nThreads)的线程,其背后使用的是无界的工作队列,任何时候最多有 nThreads 个工作线程是活动的。这意味着,如果任务数量超过了活动队列数目,将在工作队列中等待空闲线程出现;如果有工作线程退出,将会有新的工作线程被创建,以补足指定的数目 nThreads;
newSingleThreadScheduledExecutor():创建单线程池,返回ScheduledExecutorService,可以进行定时或周期性的工作调度;
newScheduledThreadPool(int corePoolSize):和newSingleThreadScheduledExecutor()类似,创建的是个 ScheduledExecutorService,可以进行定时或周期性的工作调度,区别在于单一工作线程还是多个工作线程;
newWorkStealingPool(int parallelism):这是一个经常被人忽略的线程池,Java8才加入这个创建方法,其内部会构建ForkJoinPool,利用Work-Stealing算法,并行地处理任务,不保证处理顺序;
ThreadPoolExecutor():是最原始的线程池创建,上面1-3创建方式都是对ThreadPoolExecutor的封装

11 线程池都有哪些状态?

running:最正常的一种状态,线程可接受新的任务,且可以处理阻塞线程的任务
shutdown:线程禁止接受新的任务,可以处理阻塞线程的任务
stop:线程禁止接受新的任务,且不处理阻塞线程的任务,且放弃当前正在处理的任务
tidying:所有线程都销毁了,会进到这种状态,会调用钩子方法 terminated();
terminated:调用完钩子方法后进入到这个状态,是线程的结束状态

12 线程池中 submit() 和 execute() 方法有什么区别?###############

execute():只能执行 Runnable 类型的任务。
submit():可以执行 Runnable 和 Callable 类型的任务。
Callable 类型的任务可以获取执行的返回值,而 Runnable 执行无返回值。

13 在 Java 程序中怎么保证多线程的运行安全?

-1尽量使用安全类使用安全类,比如 Java. util. concurrent 下的类
-2使用自动锁synchronized
-3使用手动锁Lock

14 多线程中 synchronized 锁升级的原理是什么?############不太会

synchronized 锁升级原理:在锁对象的对象头里面有一个 threadid 字段,在第一次访问的时候 threadid 为空,jvm 让其持有偏向锁,并将 threadid 设置为其线程 id,再次进入的时候会先判断 threadid 是否与其线程 id 一致,如果一致则可以直接使用此对象,如果不一致,则升级偏向锁为轻量级锁,通过自旋循环一定次数来获取锁,执行一定次数之后,如果还没有正常获取到要使用的对象,此时就会把锁从轻量级升级为重量级锁,此过程就构成了 synchronized 锁的升级。
锁的升级的目的:锁升级是为了减低了锁带来的性能消耗。在 Java 6 之后优化 synchronized 的实现方式,使用了偏向锁升级为轻量级锁再升级到重量级锁的方式,从而减低了锁带来的性能消耗。

15 什么是死锁?

线程A持有独占锁a,并尝试获取独占锁b的同时,线程B持有独占锁b,尝试获取独占锁a,就会发生两个线程各持有对方想要获取的锁,从而发生阻塞,这种现象称之为死锁

16 怎么防止死锁?

-1尽量使用 Java. util. concurrent 并发类代替自己手写锁。
-2尽量江都锁的粒度,不要几个功能公用一把锁
-3尽量减少同步代码快
-4设置超时时间,时间超出则释放锁,防止死锁

17 ThreadLocal 是什么?有哪些使用场景?###########

ThreadLocal 为每个使用该变量的线程提供独立的变量副本,所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
ThreadLocal 的经典使用场景是数据库连接和 session 管理等。

18 说一下 synchronized 底层实现原理?###########

synchronized 是由一对 monitorenter/monitorexit 指令实现的,monitor 对象是同步的基本实现单元。在 Java 6 之前,monitor 的实现完全是依靠操作系统内部的互斥锁,因为需要进行用户态到内核态的切换,所以同步操作是一个无差别的重量级操作,性能也很低。但在 Java 6 的时候,Java 虚拟机 对此进行了大刀阔斧地改进,提供了三种不同的 monitor 实现,也就是常说的三种不同的锁:偏向锁(Biased Locking)、轻量级锁和重量级锁,大大改进了其性能。

19 synchronized 和 volatile 的区别是什么?###########

volatile 是变量修饰符;synchronized 是修饰类、方法、代码段。
volatile 仅能实现变量的修改可见性,不能保证原子性;而 synchronized 则可以保证变量的修改可见性和原子性。
volatile 不会造成线程的阻塞;synchronized 可能会造成线程的阻塞。

20 synchronized 和 Lock 有什么区别?

两者比作车的话:synchronized 属于自动挡,操作方便,不过无法完成比较复杂的操作.Lock属于手动挡,操作繁琐,不过可以完成飘逸等复杂操作.
synchronized 可以给类、方法、代码块加锁;而 lock 只能给代码块加锁
synchronized 不需要手动获取锁和释放锁,使用简单,发生异常会自动释放锁,不会造成死锁;而 lock 需要自己加锁和释放锁,如果使用不当没有 unLock()去释放锁就会造成死锁。
通过 Lock 可以知道有没有成功获取锁,而 synchronized 却无法办到。

21 synchronized 和 ReentrantLock 区别是什么?

synchronized 早期的实现比较低效,对比 ReentrantLock,大多数场景性能都相差较大,但是在 Java 6 中对 synchronized 进行了非常多的改进。
主要区别如下:

ReentrantLock 使用起来比较灵活,但是必须有释放锁的配合动作;
ReentrantLock 必须手动获取与释放锁,而 synchronized 不需要手动释放和开启锁;
ReentrantLock 只适用于代码块锁,而 synchronized 可用于修饰方法、代码块等。
ReentrantLock 标记的变量不会被编译器优化;synchronized 标记的变量可以被编译器优化。

22 说一下 atomic 的原理?

atomic 主要利用 CAS (Compare And Swap) 和 volatile 和 native 方法来保证原子操作,从而避免 synchronized 的高开销,执行效率大为提升。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值