Java面试之多线程&并发篇(5)

打印 上一主题 下一主题

主题 844|帖子 844|积分 2534

媒介

本来想着给自己放松一下,刷刷博客,突然被几道面试题难倒!常用的线程池有哪些?简述一下你对线程池的明白?Java程序是怎样执行的?锁的优化机制了解吗?说说进程和线程的区别?似乎有点模糊了,那就大概看一下面试题吧。好记性不如烂键盘
*** 12万字的java面试题整理 ***
*** java核心面试知识整理 ***
*** Java高频面试讲解(知识涵盖齐全) ***
常用的线程池有哪些?


  • newSingleThreadExecutor:创建一个单线程的线程池,此线程池包管所有任务的执行次序按照任务的提交次序执行。
  • newFixedThreadPool:创建固定巨细的线程池,每次提交一个任务就创建一个线程,直到线程达到线程池的最大巨细。
  • newCachedThreadPool:创建一个可缓存的线程池,此线程池不会对线程池巨细做限定,线程池巨细完全依赖于操作系统(或者说JVM)能够创建的最大线程巨细。
  • newScheduledThreadPool:创建一个巨细无限的线程池,此线程池支持定时以及周期性执行任务的需求。
  • newSingleThreadExecutor:创建一个单线程的线程池。此线程池支持定时以及周期性执行任务的需求。
简述一下你对线程池的明白

(假如问到了这样的问题,可以睁开的说一下线程池怎样用、线程池的利益、线程池的启动计谋)合理使用线程池能够带来三个利益。
第一:降低资源消耗。通过重复使用已创建的线程降低线程创建和烧毁造成的消耗。
第二:进步响应速率。当任务到达时,任务可以不必要等到线程创建就能立刻执行。
第三:进步线程的可管理性。线程是稀缺资源,假如无限定的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
Java程序是怎样执行的

我们日常的工作中都使用开发工具(IntelliJ IDEA 或 Eclipse 等)可以很方便的调试程序,或者是通过打包工具把项目打包成 jar 包或者 war 包,放入 Tomcat 等 Web 容器中就可以正常运行了,但你有没有想过 Java 程序内部是怎样执行的?其实不论是在开发工具中运行还是在 Tomcat 中运行,Java 程序的执行流程基本都是相同的,它的执行流程如下:

  • 先把 Java 代码编译成字节码,也就是把 .java 类型的文件编译成 .class 类型的文件。这个过程的大致执行流程:Java 源代码 -> 词法分析器 -> 语法分析器 -> 语义分析器 -> 字符码天生器 ->最终天生字节码,其中任何一个节点执行失败就会造成编译失败;
  • 把 class 文件放置到 Java 虚拟机,这个虚拟机通常指的是 Oracle 官方自带的 Hotspot JVM;
  • Java 虚拟机使用类加载器(Class Loader)装载 class 文件;
  • 类加载完成之后,会进行字节码效验,字节码效验通过之后 JVM 解释器会把字节码翻译成机器码交由操作系统执行。但不是所有代码都是解释执行的,JVM 对此做了优化,好比,以Hotspot 虚拟机来说,它自己提供了 JIT(Just In Time)也就是我们通常所说的动态编译器,它能够在运行时将热门代码编译为机器码,这个时候字节码就变成了编译执行。Java 程序执行流程图如下:

锁的优化机制了解吗?

从JDK1.6版本之后,synchronized自己也在不断优化锁的机制,有些情况下他并不会是一个很重量级的锁了。优化机制包罗自顺应锁、自旋锁、锁消除、锁粗化、轻量级锁和偏向锁。
锁的状态从低到高依次为无锁->偏向锁->轻量级锁->重量级锁,升级的过程就是从低到高,降级在
一定条件也是有可能发生的。

  • 自旋锁:由于大部分时候,锁被占用的时间很短,共享变量的锁定时间也很短,所有没有必要挂起线程,用户态和内核态的来回上下文切换严肃影响性能。自旋的概念就是让线程执行一个忙循环,可以明白为就是啥也不干,防止从用户态转入内核态,自旋锁可以通过设置-XX:+UseSpining来开启,自旋的默认次数是10次,可以使用-XXreBlockSpin设置。
  • 自顺应锁:自顺应锁就是自顺应的自旋锁,自旋的时间不是固定时间,而是由前一次在同一个锁上的自旋时间和锁的持有者状态来决定。
  • 锁消除:锁消除指的是JVM检测到一些同步的代码块,完全不存在数据竞争的场景,也就是不必要加锁,就会进行锁消除。
  • 锁粗化:锁粗化指的是有很多操作都是对同一个对象进行加锁,就会把锁的同步范围扩展到整个操作序列之外。
  • 偏向锁:当线程访问同步块获取锁时,会在对象头和栈帧中的锁记录里存储偏向锁的线程ID,之后这个线程再次进入同步块时都不必要CAS来加锁息争锁了,偏向锁会永远偏向第一个获得锁的线程,假如后续没有其他线程获得过这个锁,持有锁的线程就永远不必要进行同步,反之,当有其他线程竞争偏向锁时,持有偏向锁的线程就会开释偏向锁。可以用过设置-XX:+UseBiasedLocking开启偏向锁。
  • 轻量级锁:JVM的对象的对象头中包含有一些锁的标志位,代码进入同步块的时候,JVM将会使用CAS方式来尝试获取锁,假如更新成功则会把对象头中的状态位标记为轻量级锁,假如更新失败,当火线程就尝试自旋来获得锁。
整个锁升级的过程非常复杂,我尽力去除一些无用的环节,简单来形貌整个升级的机制。
简单点说,偏向锁就是通过对象头的偏向线程ID来对比,甚至都不必要CAS了,而轻量级锁重要就是通过CAS修改对象头锁记录和自旋来实现,重量级锁则是除了拥有锁的线程其他全部阻塞。

说说进程和线程的区别?


  • 进程是一个“执行中的程序”,是系统进行资源分配和调理的一个独立单位。
  • 线程是进程的一个实体,一个进程中拥有多个线程,线程之间共享地址空间和别的资源(所以通讯和同步等操作线程比进程更加轻易)
  • 线程上下文的切换比进程上下文切换要快很多。
    (1)进程切换时,涉及到当进步程的CPU环境的保存和新被调理运行进程的CPU环境的设置。
    (2)线程切换仅必要保存和设置少量的寄存器内容,不涉及存储管理方面的操作。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

tsx81428

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表