java面试——多线程

常见面试题

1、线程状态。
2、synchronized原理
3、对象头包含哪些内容
4、CAS原理
5、讲讲aqs
6、volatile原理
7、讲讲ThreadLocal
8、CountDownLatch了解吗
9、线程池

1、线程状态

线程状态 解释
NEW 尚未启动的线程状态,即线程创建,还未调用start方法
RUNNABLE 就绪状态(调用start,等待调度)+正在运行
BLOCKED 等待监视器锁时,陷入阻塞状态
WAITING 等待状态的线程正在等待另一线程执行特定的操作(如notify)
TIMED_WAITING 具有指定等待时间的等待状态
TERMINATED 线程完成执行,终止状态
image.png

常用方法

wait()和sleep():

  • wait属于TIMED_WATING,自动被唤醒。属于Object类的方法。wait属于WATING,需要手动唤醒
  • sleep()只会让出CPU,不会导致锁行为的改变。Object.wait()不仅让出CPU,还会释放锁资源
  • sleep()可以在持有锁或者不持有锁的时候执行。wait()必须在持有锁的时候才可以执行

PS:为什么wait方法必须在持有锁的时候才能执行?

wait方法会将持有锁的线程从owner扔到waitSet集合中,这个操作实在修改ObjectMonitor对象,如果没有持有synchronized锁的话,是无法操作ObjectMonitor对象的。

并发编程的三大特性

一、原子性
原子性指一个操作是不可分割的,不可中断的,一个线程在执行时,另一个线程不会影响到他。

如何保证:
1、synchronized
2、CAS
在CPU层面保障的一个原子性,
3、Lock锁

二、可见性
可见性是基于CPU位置出现的,CPU处理速度非常快,相对CPU来说,去主存中获取数据的话就太慢了,CPU就提供了L123的三级缓存,每次去主存中拿完数据后,就会存储到CPU的三级缓存,每次去三级缓存中拿数据。

如何保证:
1、volatile
如果属性被volatile修饰,相当于会告诉CPU,对当前属性的操作,不允许使用CPU的缓存,必须去和主存操作
当写一个volatile变量时,JMM会把该线程对应的CPU缓存及时刷新到主内存找那个
当度一个volatile变量,JMM会将对应的CPU缓存中的内存设置为无效,必须去主存中重新读取共享变量

2、synchronized
synchronized也是可以解决可见性问题的。
如果涉及到了synchronized的同步代码块或者同步方法,获取锁资源之后,会将内部涉及到的变量从CPU缓存中移除,必须去主存中重新拿数据,并且释放锁之后,会立即将CPU缓存中的数据同步到主内存中

3、lock
lock锁是基于volatile实现的,lock锁内部在进行加锁和释放锁时,会对一个由volatile修饰的state属性进行加减操作。

4、final
final修饰的属性,被final修饰不能进行修改,就不需要保证可见性

三、有序性
.java文件中的内容会被编译,在执行前需要转化为CPU可以识别的指令,CPU在执行这些指令时,为了提升效率,在不影响结果的前提下,会对指令进行重排

如何保证有序性
1、as-if-serial
2、happens-before
3、volatile

2、synchronized原理

使用synchronized之后,会在编译之后在同步的代码块前后加上monitorenter和monitorexit字节码指令,依赖操作系统底层互斥锁实现,他的作用主要就是实现原子性操作和解决共享变量的内存可见性问题。

monitorenter和monitorexit会让对象在执行时,使得其锁计数器加1或者减1.每个对象在同一时间只与一个monitor(锁)相关联,而一个monitor在同一时间只能被一个线程获得,一个对象在尝试获得与这个对象相关联的monitor锁的所有权的时候,monitorenter指令会发生如下三种情况之一:

  • monitor计数器为0,意味着目前还没有被获得,那这个线程就会立刻获得然后把锁计数器+1,一旦+1,别的线程再想获取,就需要等待
  • 如果这个monitor已经拿到了这个锁的所有权,又重入了这把锁,那锁计数器就会累加,变成2,并且随着重入的次数,会一直累加
  • 这把锁已经被别的线程获取了,等待锁释放

monitorexit:

释放对于monitor的所有权,释放过程很简单,就是讲monitor的计数器减1,如果减完以后,计数器不是0,则代表刚才是重入进来的,当前线程还继续持有这把锁的所有权,如果计数器变成0,则代表当前线程不再拥有该monitor的所有权,即释放锁。

内存语义上来讲,加锁的过程会清楚工作内存中的共享变量,再从主存读取,而释放锁的过程是将工作内存中的共享变量写回主内存。

3、对象头包含哪些内容

对象在堆中存储分布.png

4、CAS原理

简单解释:CAS操作需要输入两个数值,一个旧值(期望操作前的值)和一个新值,在操作期间先比较下在旧值有没有发生变化,如果没有发生变化,才交换成新值,发生了变化则不交换。CAS操作是原子性的,但他只能保证一个共享变量的原子性操作,并且循环时间开销大,而且cas有个众所周知的问题就是ABA。

cas缺点:多线程情况下,如果都用cas的话,都相对占用部分CPU资源

cas的问题:ABA。通过版本号的方式解决

5、讲讲aqs

什么是aqs?

AbstractQueuedSynchronized抽象类,是JUC包下的一个基础类。
aqs核心思想是,如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并且将共享资源设置为锁定状态。如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制aqs是用clh队列锁实现的,即将暂时获取不到锁的线程加入到队列中。

aqs的组成部分是:
提供了一个由volatile修饰,并且采用CAS方式修改的int类型的state变量。
其次aqs种维护了一个双向链表,有head,有tail,并且每个节点都是node对象。

aqs组成部分.png

6、volatile原理

作用:
1、防止指令重排
2、实现可见性
当写一个volatile变量时,JMM会把该线程对应的工作内存中的共享变量值刷新到主内存中,
当读取一个volatile变量时,JMM会把该线程对应的工作内存置为无效,便只能去主内存中读取该变量。

7、讲讲ThreadLocal

ThreadLocal是一个将在多线程中为每一个线程创建单独的变量副本的类; 当使用ThreadLocal来维护变量时, ThreadLocal会为每个线程创建单独的变量副本, 避免因多线程操作共享变量而导致的数据不一致的情况。
ThreadLocal有一个静态内部类ThreadLocalMap,ThreadLocalMap又包含了一个entry数组,Entry本身是一个弱引用,他的key是指向ThreadLocal的弱引用,Entry具备了保存key, value键值对的能力。
弱引⽤的⽬的是为了防⽌内存泄露,如果是强引⽤那么ThreadLocal对象除⾮线程结束否则始终⽆法被回收,弱引⽤则会在下⼀次GC的时候被回收。
但是这样还是会存在内存泄露的问题,假如key和ThreadLocal对象被回收之后,entry中就存在key为null,但是value有值的entry对象,但是永远没办法被访问到,同样除⾮线程结束运⾏。
只要ThreadLocal使⽤恰当,在使⽤完之后调⽤remove⽅法删除Entry对象,实际上是不会出现这个问题。

8、CountDownLatch了解吗

image.png

CountDownLatch底层也是由AQS,用来同步一个或多个任务的常用并发工具类。

1、通过构造函数初始化传入参数实际为aqs的state变量赋值,维持计数器倒数状态。

2、当主线程调用await()方法时,当前线程会被阻塞,当state不为0时进入aqs阻塞队列等待。

3、其他线程调用countDown()时,state值原子性递减,当state值为0的时候,唤醒所有调用await方法阻塞的线程。

9、线程池

见:https://www.jianshu.com/p/63d00afb02fe

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容