全国旗舰校区

不同学习城市 同样授课品质

北京

深圳

上海

广州

郑州

大连

武汉

成都

西安

杭州

青岛

重庆

长沙

哈尔滨

南京

太原

沈阳

合肥

贵阳

济南

下一个校区
就在你家门口
+
当前位置:首页  >  技术干货

java面试题:java知识点合集(七)

发布时间:2022-07-11 17:12:00
发布人:wjy

  一. JVM 对 Java 的原生锁做了哪些优化?

  1. 自旋锁

  在线程进行阻塞的时候,先让线程自旋等待一段时间,可能这段时间其它线程已经解锁,这时就无需让线程再进行阻塞操作了。 自旋默认次数是10次。

  2. 自适应自旋锁

  自旋锁的升级,自旋的次数不再固定,由前一次自旋次数和锁的拥有者的状态决定。

  3. 锁消除

  在动态编译同步代码块的时候,JIT编译器借助逃逸分析技术来判断锁对象是否只被一个线程访问,而没有其他线程,这时就可以取消锁了。

  4. 锁粗化

  当JIT编译器发现一系列的操作都对同一个对象反复加锁解锁,甚至加锁操作出现在循环中,此时会将加锁同步的范围粗化到整个操作系列的外部。

  锁粒度:不要锁住一些无关的代码。

  锁粗化:可以一次性执行完的不要多次加锁执行。

java面试题:java知识点合集(七)

  二. 为什么wait()、notify()和 notifyAll()必须在同步方法或者同步块中被调用?

  Java中,任何对象都可以作为锁,并且 wait(),notify()等方法用于等待对象的锁或者唤醒线程,在 Java 的线程中并没有可供任何对象使用的锁,所以任意对象调用方法一定定义在Object类中。

  wait(), notify()和 notifyAll()这些方法在同步代码块中调用。

  有的人会说,既然是线程放弃对象锁,那也可以把wait()定义在Thread类里面啊,新定义的线程继承于Thread类,也不需要重新定义wait()方法的实现。然而,这样做有一个非常大的问题,一个线程完全可以持有很多锁,你一个线程放弃锁的时候,到底要放弃哪个锁?当然了,这种设计并不是不能实现,只是管理起来更加复杂。

  综上所述,wait()、notify()和notifyAll()方法要定义在Object类中。

  三. Java 如何实现多线程之间的通讯和协作?

  可以通过中断 和 共享变量的方式实现线程间的通讯和协作。

  比如说最经典的生产者-消费者模型。当队列满时,生产者需要等待队列有空间才能继续往里面放入商品,而在等待的期间内,生产者必须释放对临界资源(即队列)的占用权。因为生产者如果不释放对临界资源的占用权,那么消费者就无法消费队列中的商品,就不会让队列有空间,那么生产者就会一直无限等待下去。因此,一般情况下,当队列满时,会让生产者交出对临界资源的占用权,并进入挂起状态。然后等待消费者消费了商品,然后消费者通知生产者队列有空间了。同样地,当队列空时,消费者也必须等待,等待生产者通知它队列中有商品了。这种互相通信的过程就是线程间的协作。

  Java中线程通信协作的最常见的两种方式:

  syncrhoized加锁的线程的Object类的wait()/notify()/notifyAll()

  ReentrantLock类加锁的线程的Condition类的await()/signal()/signalAll()

  通过管道进行线程间通信:

  字节流;

  字符流

  四. Thread 类中的 yield 方法有什么作用?

  yield()应该做的是让当前运行线程回到可运行状态,以允许具有相同优先级的其他线程获得运行机会。因此,使用yield()的目的是让相同优先级的线程之间能适当的轮转执行。但是,实际中无法保证yield()达到让步目的,因为让步的线程还有可能被线程调度程序再次选中。

  结论:yield()从未导致线程转到等待/睡眠/阻塞状态。在大多数情况下,yield()将导致线程从运行状态转到可运行状态,但有可能没有效果。

  更多关于“Java培训”的问题,欢迎咨询千锋教育在线名师。千锋已有十余年的培训经验,课程大纲更科学更专业,有针对零基础的就业班,有针对想提升技术的好程序员班,高品质课程助力你实现java程序员梦想。

相关文章

抖音小店注册地址不能填写吗为什么呢

2023-09-30

抖音小店怎么进入精选联盟入口呢

2023-09-30

抖音小店怎么更改主体信息

2023-09-30

开抖音小店无货源需要多久

2023-09-30

开抖音小店需要多少费用汽车配件

2023-09-30

抖音小店在哪回复评价

2023-09-30
在线咨询 免费试学 教程领取