互联网Java工程师面试题·Java 并发编程篇·第八弹

目录

33、Java 死锁以及如何避免?

34、死锁的原因

35、怎么唤醒一个阻塞的线程

36、不可变对象对多线程有什么帮助

37、什么是多线程的上下文切换

38、如果你提交任务时,线程池队列已满,这时会发生什么这里区分一下:

39、Java 中用到的线程调度算法是什么

40、什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing)?

41、什么是自旋

42、Java Concurrency API 中的 Lock 接口(Lock interface)是什么?对比同步它有什么优势?

43、单例模式的线程安全性

44、Semaphore 有什么作用

45、Executors 类是什么?

46、线程类的构造方法、静态块是被哪个线程调用的

47、同步方法和同步块,哪个是更好的选择?

48、Java 线程数过多会造成什么异常?

49、short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?

50、Java 有没有 goto?


33、Java 死锁以及如何避免?

Java 中的死锁是一种编程情况,其中两个或多个线程被永久阻塞,Java 死锁情况出现至少两个线程和两个或更多资源。

Java 发生死锁的根本原因是:在申请锁时发生了交叉闭环申请。


34、死锁的原因

1、是多个线程涉及到多个锁,这些锁存在着交叉,所以可能会导致了一个锁依赖的闭环。

例如:线程在获得了锁 A 并且没有释放的情况下去申请锁 B,这时,另一个线程已经获得了锁 B,在释放锁 B 之前又要先获得锁 A,因此闭环发生,陷入死锁循环。

2、默认的锁申请操作是阻塞的。

所以要避免死锁,就要在一遇到多个对象锁交叉的情况,就要仔细审查这几个对象的类中的所有方法,是否存在着导致锁依赖的环路的可能性。总之是尽量避免在一个同步方法中调用其它对象的延时方法和同步方法。


35、怎么唤醒一个阻塞的线程

如果线程是因为调用了 wait()、sleep()或者 join()方法而导致的阻塞,可以中断线程,并且通过抛出 InterruptedException 来唤醒它;如果线程遇到了 IO 阻塞,无能为力,因为 IO 是操作系统实现的,Java 代码并没有办法直接接触到操作系统。


36、不可变对象对多线程有什么帮助

前面有提到过的一个问题,不可变对象保证了对象的内存可见性,对不可变对象的读取不需要进行额外的同步手段,提升了代码执行效率。


37、什么是多线程的上下文切换

多线程的上下文切换是指 CPU 控制权由一个已经正在运行的线程切换到另外一个就绪并等待获取 CPU 执行权的线程的过程。


38、如果你提交任务时,线程池队列已满,这时会发生什么这里区分一下:

1、如果使用的是无界队列 LinkedBlockingQueue,也就是无界队列的话,没关系,继续添加任务到阻塞队列中等待执行,因为 LinkedBlockingQueue 可以近乎认为是一个无穷大的队列,可以无限存放任务

2、如果使用的是有界队列比如 ArrayBlockingQueue,任务首先会被添加到ArrayBlockingQueue 中,ArrayBlockingQueue 满了,会根据maximumPoolSize 的值增加线程数量,如果增加了线程数量还是处理不过来,ArrayBlockingQueue 继续满,那么则会使用拒绝策略RejectedExecutionHandler 处理满了的任务,默认是 AbortPolicy


39、Java 中用到的线程调度算法是什么

抢占式。一个线程用完 CPU 之后,操作系统会根据线程优先级、线程饥饿情况等数据算出一个总的优先级并分配下一个时间片给某个线程执行。


40、什么是线程调度器(Thread Scheduler)和时间分片(Time Slicing)?

        线程调度器是一个操作系统服务,它负责为 Runnable 状态的线程分配 CPU 时间。一旦我们创建一个线程并启动它,它的执行便依赖于线程调度器的实现。时间分片是指将可用的 CPU 时间分配给可用的 Runnable 线程的过程。分配 CPU 时间可以基于线程优先级或者线程等待的时间。线程调度并不受到 Java 虚拟机控制,所以由应用程序来控制它是更好的选择(也就是说不要让你的程序依赖于线程的优先级)。


41、什么是自旋

        很多 synchronized 里面的代码只是一些很简单的代码,执行时间非常快,此时等待的线程都加锁可能是一种不太值得的操作,因为线程阻塞涉及到用户态和内核态切换的问题。既然 synchronized 里面的代码执行得非常快,不妨让等待锁的线程不要被阻塞,而是在 synchronized 的边界做忙循环,这就是自旋。如果做了多次忙循环发现还没有获得锁,再阻塞,这样可能是一种更好的策略。


42、Java Concurrency API 中的 Lock 接口(Lock interface)是什么?对比同步它有什么优势?

Lock 接口比同步方法和同步块提供了更具扩展性的锁操作。他们允许更灵活的结构,可以具有完全不同的性质,并且可以支持多个相关类的条件对象。

它的优势有:

1、可以使锁更公平

2、可以使线程在等待锁的时候响应中断

3、可以让线程尝试获取锁,并在无法获取锁的时候立即返回或者等待一段时间

4、可以在不同的范围,以不同的顺序获取和释放锁


43、单例模式的线程安全性

老生常谈的问题了,首先要说的是单例模式的线程安全意味着:某个类的实例在多线程环境下只会被创建一次出来。单例模式有很多种的写法,我总结一下:

1、饿汉式单例模式的写法:线程安全

2、懒汉式单例模式的写法:非线程安全

3、双检锁单例模式的写法:线程安全


44、Semaphore 有什么作用

Semaphore 就是一个信号量,它的作用是限制某段代码块的并发数。Semaphore有一个构造函数,可以传入一个 int 型整数 n,表示某段代码最多只有 n 个线程可以访问,如果超出了 n,那么请等待,等到某个线程执行完毕这段代码块,下一个线程再进入。由此可以看出如果 Semaphore 构造函数中传入的 int 型整数 n=1,相当于变成了一个 synchronized 了。


45、Executors 类是什么?

Executors 为 Executor,ExecutorService,ScheduledExecutorService,ThreadFactory 和 Callable 类提供了一些工具方法。Executors 可以用于方便的创建线程池。


46、线程类的构造方法、静态块是被哪个线程调用的

这是一个非常刁钻和狡猾的问题。请记住:线程类的构造方法、静态块是被 new这个线程类所在的线程所调用的,而 run 方法里面的代码才是被线程自身所调用的。

如果说上面的说法让你感到困惑,那么我举个例子,假设 Thread2 中 new 了Thread1,main 函数中 new 了 Thread2,那么:

1、Thread2 的构造方法、静态块是 main 线程调用的,Thread2 的 run()方法是Thread2 自己调用的;

2、Thread1 的构造方法、静态块是 Thread2 调用的,Thread1 的 run()方法是Thread1 自己调用的。


47、同步方法和同步块,哪个是更好的选择?

同步块,这意味着同步块之外的代码是异步执行的,这比同步整个方法更提升代码的效率。请知道一条原则:同步的范围越小越好。


48、Java 线程数过多会造成什么异常?

1、线程的生命周期开销非常高

2、消耗过多的 CPU 资源

如果可运行的线程数量多于可用处理器的数量,那么有线程将会被闲置。大量空闲的线程会占用许多内存,给垃圾回收器带来压力,而且大量的线程在竞争 CPU资源时还将产生其他性能的开销。

3、降低稳定性

JVM 在可创建线程的数量上存在一个限制,这个限制值将随着平台的不同而不同,并且承受着多个因素制约,包括 JVM 的启动参数、Thread 构造函数中请求栈的大小,以及底层操作系统对线程的限制等。如果破坏了这些限制,那么可能抛出OutOfMemoryError 异常。


49、short s1 = 1; s1 = s1 + 1;有错吗?short s1 = 1; s1 += 1;有错吗?

对于 short s1 = 1; s1 = s1 + 1;由于 1 是 int 类型,因此 s1+1 运算结果也是 int型,需要强制转换类型才能赋值给 short 型。而 short s1 = 1; s1 += 1;可以正确编译,因为 s1+= 1;相当于 s1 = (short)(s1 + 1);其中有隐含的强制类型转换。


50、Java 有没有 goto?

        goto 是 Java 中的保留字,在目前版本的 Java 中没有使用。(根据 James Gosling(Java 之父)编写的《The Java Programming Language》一书的附录中给出了一个 Java 关键字列表,其中有 goto 和 const,但是这两个是目前无法使用的关键字,因此有些地方将其称之为保留字,其实保留字这个词应该有更广泛的意义,因为熟悉 C 语言的程序员都知道,在系统类库中使用过的有特殊意义的单词或单词的组合都被视为保留字)


要想了解更多:

千题千解·Java面试宝典_时光の尘的博客-CSDN博客

互联网Java工程师面试题·Java 并发编程篇·第八弹_第1张图片

你可能感兴趣的:(千题千解·Java面试宝典,java,开发语言,Executors,Semaphore,goto,服务器)