Java面试-多线程问题整理

1.如何让线程顺序执行:

1.thread.join 方法,可以让主线程等待子线程执行完之后,再执行。 jion方法内部是调的Object.wait()方法,即让调用该方法的线程等待,一直到子线程执行完。

2.Executor.newSingleThreadExecutors().submit(Thread)方法,也可以把线程挨着顺序submit,结果也是一样。这个newSingleThreadExecutors()内部维护了一个队列,将线程存储在一个队列里面,因此也可以达到顺序执行的效果。

2. synchronized和volitale 的区别?

简单点说,volatile 能保证共享变量的内存可见性已经有序性。synchronzied保证了可见性,原子性,有序性。

理解下这三个概念,可以看下 Java并发编程实践的第2、3章,java内存模型(JMM)参考 深入理解java虚拟机12章。

JMM决定一个线程对共享变量的写入何时对另外一个线程可见,它主要定义了java线程从内存里取变量和写变量到内存的操作。java线程是通过线程的工作内存来读写主内存里的变量,读取时从工作内存的变量副本取值,如果工作内存里没有变量副本就从主内存load进来,写入时写到工作内存的变量副本再同步回主内存。

volatile 能保证共享变量的内存可见性已经有序性。也就是说定义为volatile的变量,在写操作时,会立即把新值同步回主内存,在读取前立即从主内存刷新。因为volatile变量赋值操作之后,JVM为其加了一个lock指令,这个lock指令使得当前变量副本里的值立即写入主内存,同时会让别的线程的工作内存副本无效。而且这个指令相当于一个内存屏障,在指令重排序时不能把后面的指令排到内存屏障之前,也就是volatile变量写入内存前所有操作都执行完了,才会执行后面的操作。但是volatile不能保证复合操作的原子性,如读取 修改 写入 i++。

synchronized修饰的方法或者代码块,在字节码文件中会生成一个monitorenter {代码块}monitorexit的指令,只有拿到该对象锁的线程才能访问这个代码块,其他没有拿到锁的线程会被加入一个队列,等待,直到monitorexit指令执行,会通知其他线程取获取锁。也就是synchronized是通过同一时间只能有一个线程访问该代码块来保证可见性,原子性,有序性的。

3. Lock和synchronized的区别?

1.synchronized是一个关键字,是jvm内置锁;Lock是java接口,是用java代码实现的锁。

2.synchronized锁的释放是被动的:线程执行完同步代码块或者方法,JVM会释放锁;执行出现异常,JVM也会释放锁。 Lock可以主动释放锁,需要显示调用unlock()方法。

  Lock接口有多个实现:

ReadWriteLock,读写锁,读操作用读锁,写操作用写锁,可以使得多个线程可以同时执行读操作。

ReentrantLock,可重入的,提供了以下三种功能:可中断锁,可以中断正在等待锁的线程;有条件的锁;公平、非公平锁。

ReentrantReadWriteLock

4. 线程的几种状态?

线程一共有 6 种状态(NEW、RUNNABLE、BLOCKED、WAITING、TIME_WAITING、TERMINATED)

1.初始状态 new:t=new Thread()

2.可运行状态 runnabe:t.start(),(runnabe并不代码线程就在运行了,需要线程先获得CPU时间片,在执行程序代码,此时才会运行)

3.阻塞状态:阻塞状态,表示线程进入等待状态,也就是线程因为某种原因放弃了 CPU 使用权,阻塞也分为几种情况

    1.t.sleep(),t.jion进入阻塞状态,sleep状态超时或者t.jion子线程执行完,重新进入runnable状态。

    2.o.wait(), JVM会把线程放进等待队列,wait时间结束或者被其他线程notify、notifyall,进入锁定,等到获取锁的线程重新进入runable状态

    3.线程遇到同步代码块,进入锁定状态,等到获取锁的线程重新进入runable状态

sleep不会释放锁,wait会释放锁

4. TIME_WAITING:超时等待状态,超时以后自动返回

5.结束:线程执行完毕,或者线程异常

如何测试调了某个方法后,线程处于什么状态,用jstack打印堆栈信息,即可看到线程状态。

5. Thread.join和CountDonwLatch比较:

1. join方法必须等子线程执行完成,当前线程才能继续执行。

    join方法内部是用一个while循环来不停检测join线程是否存活,存活就让主线程继续等待,直到join线程中止后,线程的this.notifyAll会被调用,主线程继续执行。

2. CountDownlatch是只要计数器变为0,调用await()的线程就就可以继续往下执行,不需要管其他线程是否执行完成,控制更灵活。

    CountDownLatch用给定的计数初始化 CountDownLatch。调用countDown()方法,计数减1。在当前计数到达零之前,调用await()方法的线程会一直受阻塞。

    当前计数到达0之后,会释放所有等待的线程。

    CyclicBarrier是可以重置计数,CountDownLatch的计数只能初始化一次。

6.ThreadPoolExecutor(这个面试问的挺多)

1. 核心类是ThreadPoolExecutor, 是线程池的实现类,可以通过Executors工具类提供的静态方法创建不同的线程池。

主要参数:corePool(核心线程池大小),maxmumPool(最大线程池大小),BlockingQueue,空闲线程存活时间

2.Executors工具类

通过Executors工具类可以创建不同的线程池ThreadPoolExecutor:SingleThreadExecutor、FixedThreadPool和CachedThreadPool。两个关键问题:

如何选择使用哪种线程池??看业务,不过个人理解FixedThreadPool这个用的多,CachedThreadPool这个会无限制

的创建线程,如果任务一直提交且其他线程一直被占用,如果任务执行可能出现这种情况,就不能用CachedThreadPool。

如何设置线程池参数?以下是网上的一些经验之谈

计算密集型: 线程数 = CPU核数+1(jdk1.8以前)  线程数 = CPU内核线程数*2(jdk1.8)

IO密集型:线程数 = CPU核心数/(1-阻塞系数),阻塞系数一般

为0.8~0.9之间,也可以取0.8或者0.9,

    套用公式,对于双核CPU来说,它比较理想的线程数就是20,当然这都不是绝对的,需要根据实际情况以及实际业务来调整

3.ThreadPoolExecutor执行顺序

当线程数小于核心线程数时,创建线程。

当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。

当线程数大于等于核心线程数,且任务队列已满

若线程数小于最大线程数,创建线程

若线程数等于最大线程数,抛出异常,拒绝任务

Executor,ReentrantLock、CountDownLatch等具体代码使用,可以看下Java编程思想第21章,有很多实例。

后续计划看下Java并发编程实战,再不定期更新。

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

推荐阅读更多精彩内容

  • 本文是我自己在秋招复习时的读书笔记,整理的知识点,也是为了防止忘记,尊重劳动成果,转载注明出处哦!如果你也喜欢,那...
    波波波先森阅读 11,224评论 4 56
  • 继《追风筝的人》之后,这是胡赛尼的第二本,战乱中的阿富汗,两个不同年龄段的女人因为命运而缔结在了一起,她们忍耐,妥...
    15廖淑君阅读 125评论 0 0
  • 文丨十一 图丨源自网络 1 原来你在这里,但愿后会有期。三年未见,这是李云霄见面开口说的第一句话。 什么?小鱼不解...
    11点姑娘阅读 4,674评论 10 23
  • 天地昏黄 我于其间 尘沙漫卷 遮日蔽天 我的左眼火山喷发 熔岩如瀑 右眼中星云闪烁 一瞬间宇宙生 一瞬间宇宙灭 双...
    柠小檬1314阅读 260评论 0 0
  • 看不清未知的旅程 通向心灵的憧憬 我在孤寂的荒野 歌唱寂寥的人生 你看那璀璨的星空 照亮了谁的梦 你是谁的梦 谁又...
    小兵黄道明阅读 173评论 1 4