八股(第一天)

java有哪几种方式创建线程?

五种,分别是

1.使用Thread创建

2.使用Runnable接口实现run方法再使用Thread开启线程

3.使用Callable接口实现call方法将它放入FutureTask中实现然后开启线程

4.因为Runnable只有一个方法声明,所以它为函数式接口,可以用Lambda表达式写。

5.使用线程池开启线程。

为啥不建议用Executors来创建线程池?

因为看下面两张图

八股(第一天)_第1张图片

八股(第一天)_第2张图片 

 它的底层都是用的LinkedBlockingQueue都是无界的(?)所以容易使得内存溢出(oom),而且它没有办法为线程命名不利于排查问题,所以不推荐使用。

线城池有哪几种状态?

RUNNING

表示此线程池正在工作,能过接受新任务的派送并处理

SHUTDOWN

表示线程池不接受新任务,但是可以继续处理旧任务。

STOP

表示线程池不接受新任务,并且久任务也会停下处理。

TIDYING

表示线程池所有的线程下的任务都已经停下了,然后回调用TERMINATED()的方法。我们可以重写TERMINATED()方法来处理业务逻辑。

TERMINATED

表示线程池完全关闭。

Sychronized 和ReentrantLock 有哪些不同点?不是很懂

八股(第一天)_第3张图片

 ThreadLocal有哪些应用场景?它底层是如何实现的。

八股(第一天)_第4张图片

 八股(第一天)_第5张图片

看上图我们可以看到,线程类下有个对象属性叫做ThreadLocal,所以我们这个线程需要往里面存啥就往里放啥。

那为啥网上经常说ThreadLocal每次放完不用的时候需要将它remove呢?

八股(第一天)_第6张图片

看上面这张图,对于这个map中的Entry每个都继承了弱引用,所以不需要担心key值的泄露问题,但是它的value是一个强引用,有人就会明白了,你如果每次使用完 ThreadLocal将它设置为空不就得了,因为这样其value的也会因为强引用的消失而被gc回收掉,没错正常情况是这样的,remove一定就是这么做的,但是我们看一下源码真的是这么做的嘛?

八股(第一天)_第7张图片

 八股(第一天)_第8张图片

 我们发现会比我们想的复杂的多。因为其实我们没有考虑到一种情况,那就是如果我们这条线程迟迟没有结束,但是我们这个里面的变量其实早就不用了,为了不占用内存,其实我们需要在不需要它的时候手动的将Entary所对应的value删掉。

ReentrantLock分为公平锁和非公平锁,它的底层是如何实现的?

如果是公平锁:那么每个线程都是乖乖排队去取锁。

如果是非公平锁:那么每个线程就都会去插队

ps:这里我们要注意,非公平和公平只体现在争锁的阶段,但是不体现在唤醒锁的阶段,唤醒锁是先唤醒排在第一个的锁上的。

偏向锁:此时所只有一个线程在使用,所以对于这个线程来讲这个只为他所用的锁就是偏向锁。

轻量级锁:此时有两个线程来竞争这个锁,锁于是就升级了,变为轻量级锁,先进入的线程工作中。外面的那个线程会一直自旋(这里也称为自旋锁),也就是说没要到锁的哪个线程会一直来问这个锁,里面是否为空。

重量级锁:但是如果外面的那个锁一直问不到,锁就会升级到重量级锁,此时外面那个线程就会进入睡面状态,等锁来唤醒他。

ps:注意线程从睡眠到运行这是要消耗资源的(需要操作系统去实现,比较消耗时间),如果在短时间内,线程自旋可以拿到锁,那么这个代价是要比线程睡眠然后再将它唤醒是划算的多的,但是如果时间长了,自旋消耗的资源也会超过睡眠然后唤醒所消耗的资源。

 

 可重入的意思就是偏向锁。ReentrantLock无法锁升级。

Tomcat为啥要有自己的类加载器?

看下面的图,就明白为啥了。

八股(第一天)_第9张图片

 每个应用中都有一个类,那么如果这两个应用开启之后,用的又都是同一个类加载器,那么就会出现问题,因为你原先搞出来的类可能作用不同,但是因为现在同名,所以你声明的两个类可能就只会生出来一个,此时你的另一个类就没有意义了。

JDK,JRE,JVM 有啥区别

jdk就是说我们程序员需要用的类库还有将Java代码编译为Java字节码的编译器,还有就是Java运行的环境。

jre就是我们客户拿到我们的Java程序需要的,只要有它就可以运行编译完成的Java字节码文件。包括jvm,还有运行jvm运行需要的类库。

jvm是Java可以跨平台的主要原因,因为Java字节码并不能直接给操作系统来运行需要将Java字节码准换为机器指令才能让操作系统执行,但是同时jvm就需要为不同的操作系统准备不同的版本,因为每个操作系统上的机器操作指令不同。

HashCode和equals有啥区别

hashcode只是将类的信息hash后做一次比较,但是会出现重复的hash值。所以我们一般都是先用hash判断之后,

1.如果两个对象是hash值不相等一定不是相同的对象

2.如果两个对象hash值都相等不一定是相同的对象

3.如果是同一个对象,那么他们的hash一定相同。

八股(第一天)_第10张图片

 

你可能感兴趣的:(面试,职场和发展,java)