Java多线程⾯试题及答案(最新版)
Java⾯试题及答案(2022版),适⽤于应届⽣、有⼯作经验的程序员,每道都是认真筛选出的⾼频⾯试题,助⼒⼤家能到满意的⼯作!
Java多线程
下载链接:
线程是操作系统能够进⾏运算调度的最⼩单位,它被包含在进程之中,是进程中的实际运作单位,可以使⽤多线程对
进⾏运算提速。
⽐如,如果⼀个线程完成⼀个任务要100毫秒,那么⽤⼗个线程完成改任务只需10毫秒
• 并⾏:多个处理器或多核处理器同时处理多个任务。
• 并发:多个任务在同⼀个 CPU 核上,按细分的时间⽚轮流(交替)执⾏,从逻辑上来看那些任务是同时执⾏。
⼀个程序下⾄少有⼀个进程,⼀个进程下⾄少有⼀个线程,⼀个进程下也可以有多个线程来增加程序的执⾏速度。
守护线程是运⾏在后台的⼀种特殊进程。它独⽴于控制终端并且周期性地执⾏某种任务或等待处理某些发⽣的事件。在 Java 中垃圾回收线程就是特殊的守护线程。
1 、线程安全
线程安全: 就是多线程访问时,采⽤了加锁机制,当⼀个线程访问该类的某个数据时,进⾏保护,其他线程不能进⾏访问,直到该线程读取完,其他线程才可使⽤。不会出现数
据不⼀致或者数据污染。
Vector 是⽤同步⽅法来实现线程安全的, ⽽和它相似的ArrayList不是线程安全的。
2 、线程不安全
sql随机函数线程不安全:就是不提供数据访问保护,有可能出现多个线程先后更改数据造成所得到的数据是脏数据线程安全问题都是由全局变量及静态变量引起的。
若每个线程中对全局变量、静态变量只有读操作,⽽⽆写操作,⼀般来说,这个全局变量是线程安全的;若有多个
线程同时执⾏写操作,⼀般都需要考虑线程同步,否则的话就可能影响线程安全。
创建线程有三种⽅式:
• 继承 Thread 重写 run ⽅法;
• 实现 Runnable 接⼝;
• 实现 Callable 接⼝。
runnable 没有返回值,callable 可以拿到有返回值,callable 可以看作是 runnable 的补充。
线程的状态:
• NEW 尚未启动
• RUNNABLE 正在执⾏中
• BLOCKED 阻塞的(被同步锁或者IO锁阻塞)
• WAITING 永久等待状态
• TIMED_WAITING 等待指定的时间重新被唤醒的状态
• TERMINATED 执⾏完成
1 、 CAS (compare and swap)的缩写,中⽂翻译成⽐较并交换。
2 、 CAS 不通过JVM,直接利⽤java本地⽅ JNI (Java Native Interface为JAVA本地调⽤) ,直接调⽤ CPU 的cmpxchg (是汇编指令)指令。
3、利⽤CPU的CAS指令,同时借助JNI来完成Java的⾮阻塞算法,实现原⼦操作。其它原⼦操作都是利⽤类似的特性完成的。
4 、整个urrent都是建⽴在CAS之上的,因此对于synchronized阻塞算法, J.U.C在性能上有了很⼤的提升。
5 、 CAS是项乐观锁技术,当多个线程尝试使⽤CAS同时更新同⼀个变量时,只有其中⼀个线程能更新变量的值,⽽其它线程都失败,失败的线程并不会被挂起,⽽是被告知
这次竞争中失败,并可以再次尝试。
使⽤CAS在线程冲突严重时,会⼤幅降低程序性能;CAS只适合于线程冲突较少的情况使⽤。
synchronized在jdk1.6之后,已经改进优化。synchronized的底层实现主要依靠Lock-Free的队列,基本思路是⾃旋后阻塞,竞争切换后继续竞争锁,稍微牺牲了公平性,但获得了⾼吞吐量。在线程冲突较少的情况下,可以获得和CAS类似的性能;• 类的不同:sleep() 来⾃ Thread,wait() 来⾃ Object。
• 释放锁:sleep() 不释放锁;wait() 释放锁。
• ⽤法不同:sleep() 时间到会⾃动恢复;wait() 可以使⽤ notify()/notifyAll()直接唤醒。
notifyAll()会唤醒所有的线程,notify()之后唤醒⼀个线程。notifyAll() 调⽤后,会将全部线程由等待池移到锁池,然后参与锁的竞争,竞争成功则继续执⾏,如果不成功则留在锁
池等待锁被释放后再次参与竞争。⽽ notify()只会唤醒⼀个线程,具体唤醒哪⼀个线程由虚拟机控制。
start() ⽅法⽤于启动线程,run() ⽅法⽤于执⾏线程的运⾏时代码。run() 可以重复调⽤,⽽ start() 只能调⽤⼀次。
线程池创建有七种⽅式,最核⼼的是最后⼀种:
• newSingleThreadExecutor():它的特点在于⼯作线程数⽬被限制为 1,操作⼀个⽆界的⼯作队列,所以它保证了所有任务的都是被顺序执⾏,最多会有⼀个任务处于活动状
态,并且不允许使⽤者改动线程池实例,因此可以避免其改变线程数⽬;
• newCachedThreadPool():它是⼀种⽤来处理⼤量短时间⼯作任务的线程池,具有⼏个鲜明特点:它会试图缓存线程并重⽤,当⽆缓存线程可⽤时,就会创建新的⼯作线程;
如果线程闲置的时间超过 60 秒,则被终⽌并移出缓存;长时间闲置时,这种线程池,不会消耗什么资源。其内部使⽤ SynchronousQueue 作为⼯作队列;
• newFixedThreadPool(int nThreads):重⽤指定数⽬(nThreads)的线程,其背后使⽤的是⽆界的⼯作队列,任何时候最多有 nThreads 个⼯作线程是活动的。这意味着,如果
java常见笔试题任务数量超过了活动队列数⽬,将在⼯作队列中等待空闲线程出现;如果有⼯作线程退出,将会有新的⼯作线程被创建,以补⾜指定的数⽬ nThreads;
discuz素材模板• newSingleThreadScheduledExecutor():创建单线程池,返回 ScheduledExecutorService,可以进⾏定时或周期性的⼯作调度;
• newScheduledThreadPool(int corePoolSize):和newSingleThreadScheduledExecutor()类似,创建的是个 ScheduledExecutorService,可以进⾏定时或周期性的⼯作调度,
区别在于单⼀⼯作线程还是多个⼯作线程;
• newWorkStealingPool(int parallelism):这是⼀个经常被⼈忽略的线程池,Java 8 才加⼊这个创建⽅法,其内部会构建ForkJoinPool,利⽤Work-Stealing算法,并⾏地处理任
务,不保证处理顺序;
• ThreadPoolExecutor():是最原始的线程池创建,上⾯1-3创建⽅式都是对ThreadPoolExecutor的封装。
1 、悲观锁
美国总统大选拜登结果Java在JDK1.5之前都是靠synchronized关键字保证同步的,这种通过使⽤⼀致的锁定协议来协调对共享状态的访问,可以确保⽆论哪个线程持有共享变量的锁,都采⽤独占的
⽅式来访问这些变量。独占锁其实就是⼀种悲观锁,所以可以说synchronized是悲观锁。
2 、乐观锁
乐观锁( Optimistic Locking)其实是⼀种思想。相对悲观锁⽽⾔,乐观锁假设认为数据⼀般情况下不会造成冲突,所以在数据进⾏提交更新的时候,才会正式对数据的冲突与否进⾏检测,如果发现冲突了,则让返回⽤户错误的信息,
让⽤户决定如何去做。
memcached使⽤了cas乐观锁技术保证数据⼀致性。
Java通过Executors提供四种线程池,分别为:
1 、 newCachedThreadPool创建⼀个可缓存线程池,如果线程池⻓度超过处理需要,可灵活回收空闲线程,若⽆可回收,则新建线程。
2 、 newFixedThreadPool 创建⼀个定⻓线程池,可控制线程最⼤并发数,超出的线程会在队列中等待。
3 、 newScheduledThreadPool 创建⼀个定⻓线程池,⽀持定时及周期性任务执⾏。
4 、 newSingleThreadExecutor 创建⼀个单线程化的线程池,它只会⽤唯⼀的⼯作线程来执⾏任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执⾏。
1 、 JDK7提供了7个阻塞队列。(也属于并发容器)
i. ArrayBlockingQueue :⼀个由数组结构组成的有界阻塞队列。
ii. LinkedBlockingQueue :⼀个由链表结构组成的有界阻塞队列。
iii. PriorityBlockingQueue :⼀个⽀持优先级排序的⽆界阻塞队列。
iv. DelayQueue:⼀个使⽤优先级队列实现的⽆界阻塞队列。
v. SynchronousQueue:⼀个不存储元素的阻塞队列。
数的三个多音字组词注音vi. LinkedTransferQueue:⼀个由链表结构组成的⽆界阻塞队列。
vii. LinkedBlockingDeque:⼀个由链表结构组成的双向阻塞队列。
2、概念:阻塞队列是⼀个在队列基础上⼜⽀持了两个附加操作的队列。
3 、 2个附加操作:
⽀持阻塞的插⼊⽅法:队列满时,队列会阻塞插⼊元素的线程,直到队列不满。
excel表格vlookup公式
⽀持阻塞的移除⽅法:队列空时,获取元素的线程会等待队列变为⾮空。
下载链接:
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论