并发编程知识点
一、(面试题)进程和线程的区别
1、线程是进程更小的运行单位,各进程是独立的,而各线程不一定
2、一个进程产生多个线程,线程开销比进程小,但是线程不利于资源的管理和保护,进程相反。
二、线程的状态
创建状态、就绪状态、运行状态、阻塞状态、终止状态
三、启动线程有几种方式
1、继承Thread类
2、实现Runable接口并实现run()方法
3、实现Callable接口并实现call()方法
四、start()方法来运行run()和直接调用run()有什么区别?
start()方法运行run(),是启动一个新的线程来执行run()方法,是真正的多线程,直接调用run()相当于在当前线程调用了一个普通方法,并不是真正的多线程。
总结:调用 start() 方法方可启动线程并使线程进入就绪状态,直接执行 run() 方法的话不会以多线程的方式执行。
五、什么是线程上下文切换
线程上下文切换发送在同一个进程下的两个线程之间,上下文切换是某一线程的时间片用完,该线程被中断,CPU把使用权交给其他线程来执行,若干时间后该线程又继续执行未完成的部分
造成的原因:1、CPU时间片用完 2、垃圾回收导致线程中断 3、有更高优先级的线程需要执行 4、线程自己调用了阻塞方法
造成的后果:影响线程使用性能
解决方案:用CAS算法,实现无锁并发编程,尽可能地减少线程使用,避免创建不需要的线程(可以通过线程池实现)
六、synchronized和ReentrantLock的区别
1、synchronized依赖于jvm,ReentrantLock依赖于API
2、synchronized会自动释放锁,ReentrantLock需要手动开启和释放锁,lock()和unlock()
3、ReentrantLock实现了公平锁和非公平锁,synchronized实现了非公平锁
七、java内存模型JMM
抽象了线程和主内存之间的关系,线程可以把变量保存在本地内存,而不是直接在主内存中对变量进行读写。但是其他线程也可能会使用到这个本地内存的变量值,造成数据不一致的问题。
八、ThreadLocal有什么作用
保证每个线程都有自己的专属本地变量。如果创建了一个ThreadLocal变量,那么访问这个变量的每个线程都会有这个变量的本地副本,可以使用get()和set()来获取值,或者将其值更改为当前线程所存副本的值,从而避免了线程不安全
九、ThreadLocal会发生什么问题,如何解决
会发生内存泄露问题,因为ThreadLocalMap中对key是弱引用,对value是强引用,如果清理了key,key为null,就会被回收,而value不为空,就会一直存在,造成内存泄漏
解决办法就是在用完ThreadLocal方法之后,手动调用remove()方法
十、线程池的七大参数
1、核心线程数
2、最大线程数
3、可存活时间
4、存活时间单位
5、工作队列
6、现场工厂
7、拒绝策略
十一、Atomic类如何实现线程安全
Atomic类使用了CAS+volatile 和 native方法来保证原子操作,从而避免synchronized的高开销,提升执行效率
浙公网安备 33010602011771号