关于多线程面试的一些问题
2018-09-23 本文已影响0人
等风中
关于多线程的一些问题(java)
标签(空格分隔): 并发 面试
多线程
java中有几种方法可以实现一个线程?
总共有四种方法。
1.继承Thread类,此种实现方式好处是可以用父类中的一些方法对多线程进行控制
2.实现runnable接口,此种方法比较轻量,只需在runnable中实现run方法即可,并且还可继承其他父类
3.实现callable接口,增添了一个回调函数,返回future,使用futeure.get获取返回值,为非阻塞方式
4.将实现的runnable接口或callable接口扔进线程池
如何停止一个正在运行的线程?
1.在run方法中设置钩子(一个volatile的stop标志),这样通过外部可以关闭掉循环的线程
2.使用interrupt方法终止,相当于为线程添加中断标志
3.使用stop方法暴力终止
notify()和notifyAll()有什么区别?
notify是随机唤醒一个正在等待的线程
notifyAll是唤醒所有等待线程
sleep()和 wait()有什么区别?
1.从属类不同,sleep方法是Thread类的静态方法,wait方法是Object类的类方法
2.对锁的方式不同,sleep方式不会释放锁,但是wait方法会释放锁,被notify唤醒时会进入锁的阻塞队列
3.sleep必须指定时间,没有唤醒方法,而wait可以用notify或notifyAll方法唤醒
什么是Daemon线程?它有什么意义?
Daemon线程又称守护线程,就是当用户线程关闭时,即使还有守护线程没有关闭,虚拟机也会自动退出。他的意义是可以用于一些后台线程,比如垃圾回收,当用户线程都退出,gc也没什么用了,所有也会自动退出。
java如何实现多线程之间的通讯和协作?
1.共享内存:通过共享堆中的内存,可以使线程之间进行通信
2.互斥锁:对线程进行同步控制
3.
锁
什么是可重入锁(ReentrantLock)?
可重入锁即当当前线程获取到了A锁,此时它可以在进入A锁,这时A锁会维护一个值,当此线程进入时+1,当此线程释放时-1,当为0时可以被其他线程获取
当一个线程进入某个对象的一个synchronized的实例方法后,其它线程是否可进入此对象的其它方法?
分情况
1.当其他方法也是synchronized的实例方法时,其他线程因为不能获取到锁,会被阻塞,当上一个获取到实例锁的线程释放锁之后,即可进入
2.当其他方法没有被synchronized修饰,自然可以进入
synchronized和java.util.concurrent.locks.Lock的异同?
一般用ReentranLock与synchronized进行对比,因为读写锁也实现了Lock接口,但是synchronized没有与其对应的方法
1.synchornized:可用在类方法,对象方法,代码块中。类方法中加的锁是类,对象方法的锁是对象,代码块中可以指定锁。此种加锁当线程发生异常会自动释放锁。且分为偏向锁,轻量级锁,重量级锁
2.ReetranLock:可显式进行加锁,且可用condition类进行通信协调(condition类主要是用于维护一个condition队列,当调用await方法即将当前线程从AQS队列移到对应的condition队列)。其需要自己释放锁,所以一般会在其获取所之后加try finally,在finally中释放锁。且其可以设置是否为公平锁,默认为非公平锁
乐观锁和悲观锁的理解及如何实现,有哪些实现方式?
1.乐观锁:假定不会出现冲突,当检测到出现冲突进行重试,重试次数过多转化为悲观锁。一般都为数据添加一个版本号,当检测到版本号修改则发生冲突,还有就是CAS操作
2.悲观锁:假定会发生冲突,一切都以数据完整性为前提。一般实现可以直接用加独占锁实现
并发框架
SynchronizedMap和ConcurrentHashMap有什么区别?
1.SynchronizedMap是对所有方法添加了互斥锁,这样肯定可以保证强一致性
2.ConcurrentHashMap在1.7主要是使用锁段机制,对不同的段区加不同的锁,这样的话将锁的力度减小。在1.8主要使用CAS操作,在操作同一个hash值得链时会进行加锁保证线程安全。为size添加volatile标志,使用cas操作统计其长度
CopyOnWriteArrayList可以用于什么应用场景?
一般用于读多写少的使用场景,比如白名单,黑名单等,因为其在读的时候不会进行加锁,写的时候才会进行加锁拷贝数据,在写的时候如果有线程去读可能会读到旧数据
线程安全
什么叫线程安全?servlet是线程安全吗?
允许被多个线程同时执行(不会出现同步问题)的代码叫线程安全的代码。servlet不是线程安全的,因为如果有多个http请求,此时会有多个线程调用其service方法,此时如果有静态变量和实例变量就会产生线程安全问题
同步有几种实现方法?
1.synchronized
2.ReentranLock
3.CountDownLatch
4.CyclicBarrier
5.Semaphore
volatile有什么用?能否用一句话说明下volatile的应用场景?
保证变量的可见性与禁止指令重排序。
应用场景:单例,或者在多个线程之间的共享变量,如果有写操作的话,一般需要用volatile修饰
请说明下java的内存模型及其工作流程。
内存模型:java内存模型分为线程自己的栈区和主内存,所以一般线程自己的栈区和主内存会进行定期同步,这种情况下可能会造成数据延迟
为什么代码会重排序?
因为编译器和cpu可能会进行希望对执行时间进行优化