常见的java线程面试题

1.什么是线程?

线程是操作系统中能够运行的最小单位,它被包含在进程中,是进程中的实际运作单位。程序员可以通过它进行多处理器编程,你可以使用多线程对运算密集型任务提速。比如,如果一个线程完成一个任务需要100毫秒,那么用十个线程完成改任务只需10毫秒。


2.在java中实现线程的方式?

  • 继承Thread类,重写run()方法
  • 实现Runable接口,重写run()方法
  • 实现Callable接口,重写call()方法
call()方法和run()方法的区别?
  • call()方法具有返回值,且返回值类型与声明接口时定义的泛型类型一致
  • call()方法可以抛出异常

3.用什么方式创建线程比较好?
继承Thread类有一个缺点就是单继承,而实现Runnable接口则弥补了这个缺点,可以实现多继承;
继承Thread类必须产生多个Runnable实例,然后再用Thread产生多个线程;而实现Runnable接口,只需要建立一个实现这个类的实例,然后用这个实例对象产生多个线程,实现了资源的共享性。
基于上面所说,我建议使用第二种方法。

4.Thread类中的start()方法和run()方法有什么区别?
start()方法会启动线程,使线程由新建状态进入就绪状态,为线程分配程序计数器、方法栈等资源。当CPU分配时间给该线程时,由JVM调用run()方法。

5.java终止线程的四种方式?
  • 自然终止,run()方法执行结束后,线程自动终止
  • 使用stop()、suspend()和resume()的控制方法,已被弃用
  • 使用volatile标志位(其实就是外部控制的自然死亡)
  • 使用interrupt()方法中断运行态和阻塞态线程(调用interrupt()方法立即改变的是中断状态,但如果不是在阻塞态,就不会抛出异常;如果进入阻塞态后,中断状态已中断,就会立即抛出异常
6.sleep()方法和wait()方法的区别,wait()方法为什么属于Object类?
sleep()方法是Thread类下的方法,控制线程休眠,休眠的过程中不会释放锁,sleep()时间到后进入就绪态等待调度。
wait()方法是Object类下的方法,控制线程等待,等待的过程会释放锁,被notify()后会进入就绪态等待调度。

7.如何在两个线程间共享数据?
可以通过共享对象来实现,或者是使用像阻塞队列这样的并发的数据结构。另外,Object类中的wait()/nofity()/notifyAll()方法可以用于线程之间通信关于资源的锁状态。

8.什么是ThreadLocal?
ThreadLocal用于创建线程本地变量,我们知道一个对象的所有线程会共享它的全局变量,所以这些变量不是线程安全的,我们可以使用同步技术。每个线程都会拥有他们自己的Thread变量,它们可以使用get()/set()方法去获取他们的默认值或者在线程内部改变他们的值。ThreadLocal实例通常是希望它们同线程状态关联起来是private static属性。

9.为什么wait()和notify()方法要在同步块中调用?
主要是因为Java API强制要求这么做,如果不这么做,你的代码就会抛出IllegalMonitorStateException异常。还有一个原因是为了避免wait和notify之间的竞态条件。

10.什么是竞态条件?举个例子说明
竞态条件会导致程序在并发情况下出现一些bugs。多线程对一些资源的竞争的时候就会产生竞态条件,如果首先要执行的程序竞争失败排到后面执行了,那么整个程序就会出现一些不确定的bugs。

11.一个线程运行时发生异常会怎么样?
如果异常没有捕获该线程将会停止执行。Thread.UncaughtExceptionHandler是用于处理未捕获异常造成线程突然中断情况的一个内嵌接口。当一个未捕获异常将造成线程中断的时候JVM会使用Thread.getUncaughtExceptionHandler()来查询线程的UncaughtExceptionHandler并将线程和异常作为参数传递给handler的uncaughtException()方法进行处理。

12.写出3条你遵守的多线程的最佳实践?
  • 给线程起个有意义的名字
这样可以方便找bug或追踪。OrderProcessor,QuoteProcessor or TradeProcessor 这种名字比Thread-1、Thread-2、Thread-3好多了,给线程起一个和它要完成的任务相关的名字,所有的主要框架甚至JDK都遵循这个最佳实践。
  • 避免锁定和缩小同步的范围
锁花费的代价高昂且上下文切换更耗费时间空间,试试最低限度的使用同步和锁,缩小临界区。因此相对于同步方法我更喜欢同步块,它会给我拥有对锁的绝对控制权。
  • 多用同步类少用wait和notify
首先,CountDownLatc,Semaphroe,CyclicBarrier和Exchange这些同步类简化了编码的操作,而用wait和notify很难实现对复杂控制流的控制。其次,这些类是由最好的企业编写和维护在后续的JDK中它们还会不断优化和完善,使用这些更高级的同步工具你的程序可以快速的获得优化。
  • 多用并发集合少用同步集合
这是另外一个容易遵守且受益巨大的最佳实践,并发集合比同步集合的可扩展性更好,所以在并发编程时使用并发集合效果更好。







你可能感兴趣的:(java,线程,多线程)