目录
15、什么是 FutureTask?使用 ExecutorService 启动任务。
19、你将如何使用 thread dump?你将如何分析 Thread dump?
20、为什么我们调用 start()方法时会执行 run()方法,为什么我们不能直接调用 run()方法?
22、在 Java 中 CycliBarriar 和 CountdownLatch 有什么区别?
14、什么是 Callable 和 Future?
Callable
接口类似于
Runnable
,从名字就可以看出来了,但是
Runnable
不会返回结果,并且无法抛出返回结果的异常,而 Callable
功能更强大一些,被线程执行后,可以返回值,这个返回值可以被 Future
拿到,也就是说,
Future
可以拿到异步执行任务的返回值。
可以认为是带有回调的
Runnable
。
Future
接口表示异步任务,是还没有完成的任务给出的未来结果。所以说
Callable用于产生结果,Future
用于获取结果。
15、什么是 FutureTask?使用 ExecutorService 启动任务。
在
Java
并发程序中
FutureTask
表示一个可以取消的异步运算。它有启动和取消运算、查询运算是否完成和取回运算结果等方法。只有当运算完成的时候结果才能取回,如果运算尚未完成 get
方法将会阻塞。一个
FutureTask
对象可以对调用了 Callable
和
Runnable
的对象进行包装,由于
FutureTask
也是调用了
Runnable接口所以它可以提交给 Executor
来执行。
16、什么是并发容器的实现?
何为同步容器:可以简单地理解为通过
synchronized
来实现同步的容器,如果有多个线程调用同步容器的方法,它们将会串行执行。比如 Vector
,
Hashtable
,以及 Collections.synchronizedSet
,
synchronizedList
等方法返回的容器。可以通过查看 Vector
,
Hashtable
等这些同步容器的实现代码,可以看到这些容器实现线程安全的方式就是将它们的状态封装起来,并在需要同步的方法上加上关键字 synchronized
。
并发容器使用了与同步容器完全不同的加锁策略来提供更高的并发性和伸缩性,例如在 ConcurrentHashMap
中采用了一种粒度更细的加锁机制,可以称为分段锁,在这种锁机制下,允许任意数量的读线程并发地访问 map
,并且执行读操作的线程和写操作的线程也可以并发的访问 map
,同时允许一定数量的写操作线程并发地修改 map
,所以它可以在并发环境下实现更高的吞吐量。
17、多线程同步和互斥有几种实现方法,都是什么?
线程同步是指线程之间所具有的一种制约关系,一个线程的执行依赖另一个线程的消息,当它没有得到另一个线程的消息时应等待,直到消息到达时才被唤醒。线程互斥是指对于共享的进程系统资源,在各单个线程访问时的排它性。当有若干个线程都要使用某一共享资源时,任何时刻最多只允许一个线程去使用,其它要使用该资源的线程必须等待,直到占用资源者释放该资源。线程互斥可以看成是一种特殊的线程同步。
线程间的同步方法大体可分为两类:用户模式和内核模式。顾名思义,内核模式就是指利用系统内核对象的单一性来进行同步,使用时需要切换内核态与用户态,而用户模式就是不需要切换到内核态,只在用户态完成操作。
用户模式下的方法有:原子操作(例如一个单一的全局变量),临界区。内核模式下的方法有:事件,信号量,互斥量。
18、什么是竞争条件?你怎样发现和解决竞争?
当多个进程都企图对共享数据进行某种处理,而最后的结果又取决于进程运行的顺序时,则我们认为这发生了竞争条件(race condition
)。
19、你将如何使用 thread dump?你将如何分析 Thread dump?
新建状态(
New
)
用
new
语句创建的线程处于新建状态,此时它和其他
Java
对象一样,仅仅在堆区中被分配了内存。
就绪状态(
Runnable
)
当一个线程对象创建后,其他线程调用它的
start()
方法,该线程就进入就绪状态,Java 虚拟机会为它创建方法调用栈和程序计数器。处于这个状态的线程位于可运行池中,等待获得 CPU
的使用权。
运行状态(
Running
)
处于这个状态的线程占用
CPU
,执行程序代码。只有处于就绪状态的线程才有机会转到运行状态。
阻塞状态