点击上方“蓝字”关注我们
1 Q:创建线程的有哪些方式?
1、继承 Thread 类创建线程类
2、通过 Runnable 接口创建线程类
3、通过 Callable 和 Future 创建线程
4、通过线程池创建
2 Q:创建线程的三种方式的对比?
1、采用实现 Runnable、Callable 接口的方式创建多线程。优势是:线程类只是实现了 Runnable 接口或 Callable 接口,还可以继承其他类。在这种方式下,多个线程可以共享同一个 target 对象,所以非常适合多个相同线程来处理同一份资源的情况,从而可以将 CPU、代码和数据分开,形成清晰的模型,较好地体现了面向对象的思想。劣势是:编程稍微复杂,如果要访问当前线程,则必须使用 Thread.currentThread()方法。
2、使用继承 Thread 类的方式创建多线程。优势是:编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread()方法,直接使用 this即可获得当前线程。劣势是:线程类已经继承了 Thread 类,所以不能再继承其他父类。
3、Runnable 和 Callable 的区别:
(1)Callable 规定(重写)的方法是 call(),Runnable 规定(重写)的方法是 run()。
(2)Callable 的任务执行后可返回值,而 Runnable 的任务是不能返回值的。
(3)Call 方法可以抛出异常,run 方法不可以。
(4)运行 Callable 任务可以拿到一个 Future 对象,表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。通过 Future 对象可以了解任务执行情况,可取消任务的执行,还可获取执行结果
3 Q:Java 线程具有五种基本状态?
1、新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t= new MyThread();
2、就绪状态(Runnable):当调用线程对象的 start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待 CPU 调度执行,并不是说执行了 t.start()此线程立即就会执行;
3、运行状态(Running):当 CPU 开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
4、阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对 CPU 的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被 CPU 调用以进入到运行状态。
5、死亡状态(Dead):线程执行完了或者因异常退出了 run()方法,该线程结束生命周期。
4 Q:四种线程池的创建?
1、newCachedThreadPool 创建一个可缓存线程池
2、newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数。
3、newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
4、newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务。
5 Q:synchronized 的作用?与ReentrantLock 的区别
在 Java 中,synchronized 关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized 代码段不被多个线程同时执行。synchronized 既可以加在一段代码上,也可以加在方法上。
synchronized 是和 if、else、for、while 一样的关键字,ReentrantLock 是类,这是二者的本质区别。既然 ReentrantLock 是类,那么它就提供了比 synchronized 更多更灵活的特性,可以被继承、可以有方法、可以有各种各样的类变量,ReentrantLock 比 synchronized 的扩展性体现在几点上:
(1)ReentrantLock 可以对获取锁的等待时间进行设置,这样就避免了死锁; (2)ReentrantLock 可以获取各种锁的信息;
(3)ReentrantLock 可以灵活地实现多路通知;
另外,二者的锁机制其实也是不一样的。
6 Q:volatile 关键字的作用?
对于可见性,Java 提供了 volatile 关键字来保证可见性。当一个共享变量被 volatile 修饰时,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,它会去内存中读取新值。从实践角度而言,volatile 的一个重要作用就是和 CAS 结合,保证了原子性。
7 Q:ThreadLocal 是什么?有什么用?
ThreadLocal 是一个本地线程副本变量工具类。主要用于将私有线程和该线程存放的副本对象做一个映射,各个线程之间的变量互不干扰,在高并发场景下,可以实现无状态的调用,特别适用于各个线程依赖不同的变量值完成操作的场景。简单说 ThreadLocal 就是一种以空间 换 时 间 的 做 法 , 在 每 个 Thread 里 面 维 护 了 一 个 以 开 地 址 法 实 现 的ThreadLocal.ThreadLocalMap,把数据进行隔离,数据不共享,自然就没有线程安全方面的问题了。
8 Q:ReadWriteLock 是什么?
首先明确一下,不是说 ReentrantLock 不好,只是 ReentrantLock 某些时候有局限。如果使用 ReentrantLock,可能本身是为了防止线程 A 在写数据、线程 B 在读数据造成的数据不一致,但这样,如果线程 C 在读数据、线程 D 也在读数据,读数据是不会改变数据的,没有必要加锁,但是还是加锁了,降低了程序的性能。因为这个,才诞生了读写锁ReadWriteLock 。ReadWriteLock 是 一 个 读 写 锁 接 口 , ReentrantReadWriteLock 是ReadWriteLock 接口的一个具体实现,实现了读写的分离,读锁是共享的,写锁是独占的,读和读之间不会互斥,读和写、写和读、写和写之间才会互斥,提升了读写的性能。
扫码二维码
获取更多精彩
IT学习小镇