首页 > 编程语言 > 详细

Java面试--线程

时间:2021-06-29 00:34:44      阅读:23      评论:0      收藏:0      [点我收藏+]

JAVA如何开启线程?

1、继承Thread类,重写run方法。
2、实现Runnable接口,实现run方法。
3、实现Callable接口,实现call方法。通过FutureTask创建一个线程,获取到线程执行的返回值。
4、通过线程池来开启线程。

怎么保证线程安全?
1、 JVM提供的锁, 也就是Synchronized关键字。
2、 JDK提供的各种锁 Lock。

 Volatile和Synchronized有什么区别?

Synchronized关键字,用来加锁。

Volatile只是保持变量的线程可见性。

通常适用于一个线程写,多个线程读的场景。

Volatile能不能保证线程安全?

不能。Volatile关键字只能保证线程可见性, 不能保证原子性。

DCL(Double Check Lock)单例为什么要加Volatile?

Volatile防止指令重排。在DCL中,防止高并发情况下,指令重排造成的线程安全问题。

DCL(Double Check Lock)单例:

  在锁的前面后面各加一次判断(保证严格单例、双重检查锁)

指令重排:

  编译器优化的重排序。编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序

CPU在底层创建一个对象的步骤:

  分配内存 --> 对象初始化 --> 建立指针对应关系

  若发生指令重排,有可能顺序改变:

  分配内存 --> 建立指针对应顺序 --> 对象初始化

  有可能会造成:一个线程存储一个值为8,内存是0,但执行的顺序改变了,指针先指向0,后初始话,另一个线程调用时,调用的数值不是8,而是0

偏向锁、轻量级锁、重量级锁有什么区别?

偏向锁:只有一个线程进入临界区;

轻量级锁:多个线程交替进入临界区;

重量级锁:多个线程同时进入临界区。

偏向所锁,轻量级锁都是乐观锁,重量级锁是悲观锁。

java偏向锁,轻量级锁与重量级锁为什么会相互膨胀?

一个对象刚开始实例化的时候,没有任何线程来访问它的时候,它是可偏向的;

线程来访问它的时候,它会偏向这个线程,此时,对象持有偏向锁;

一旦有第二个线程访问这个对象,因为偏向锁不会主动释放,所以第二个线程可以看到对象时偏向状态,这时表明在这个对象上已经存在竞争了,检查原来持有该对象锁的线程是否依然存活,如果挂了,则可以将对象变为无锁状态,然后重新偏向新的线程,如果原来的线程依然存活,则马上执行那个线程的操作栈,检查该对象的使用情况,如果仍然需要持有偏向锁,则偏向锁升级为轻量级锁。如果不存在使用了,则可以将对象回复成无锁状态,然后重新偏向;

轻量级锁认为竞争存在,但是竞争的程度很轻,一般两个线程对于同一个锁的操作都会错开,或者说稍微等待一下(自旋),另一个线程就会释放锁。 但是当自旋超过一定的次数,或者一个线程在持有锁,一个在自旋,又有第三个来访时,轻量级锁膨胀为重量级锁,重量级锁使除了拥有锁的线程以外的线程都阻塞,防止CPU空转。

 

Java面试--线程

原文:https://www.cnblogs.com/chilly-night/p/14947811.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!