每日五题-Java面试题220810

1、TreeMap 和 TreeSet 在排序时如何比较元素? Collections 工具类中的 sort() 方法如何比较元素?

TreeSet 要求存放的对象所属的类必须实现 Comparable 接口,该接口提供了比较元素的 compareTo() 方法,当插入元素时会回调该方法比较元素的大小。 TreeMap 要求存放的键值对映射的键必须实现 Comparable 接口从而根据键对元素进行排序。Collections 工具类的 sort 方法有两种重载的形式,第一种要求传入的待排序容器中存放的对象比较实现 Comparable 接口以实现元素的比较;第二种不强制性的要求容器中的元素必须可比较,但是要求传入第二个参数,参数是Comparator 接口的子类型(需要重写 compare 方法实现元素的比较),相当于一个临时定义的排序规则,其实就是通过接口注入比较元素大小的算法,也是对回调模式的应用(Java 中对函数式编程的支持)。

2、Thread 类的 sleep() 方法和对象的 wait() 方法都可以让线程暂停执行,它们有什么区别?

sleep() 方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复(线程回到就绪状态)。wait() 是 Object 类的方法,调用对象的wait() 方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的notify() 方法或(notifyAll() 方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。

补充
可能不少人对什么是进程,什么是线程还比较模糊,对于为什么需要多线程编程也不是特别理解。简单的说:进程是具有一定独立功能的程序关于某个数据集合上的一次运行活动,是操作系统进行资源分配和调度的一个独立单位;线程是进程的一个实体,是 CPU 调用和分派的基本单位,是比进程更小的能独立运行的基本单位。线程的划分尺度小于进程,这使得多线程的编程通常能够带来更好的性能和用户体验,但是多线程的程序对于其他程序是不友好的,因为它可能占用了更多的CPU 资源。当然,也不是线程越多,程序的性能就越好,因为线程之间的调度和切换也会浪费 CPU 时间。 时下很时髦的 Node.js 就采用了单线程异步 I/O 的工作模式。

3、线程的 sleep() 方法和 yield() 方法有什么区别?

  1. sleep() 方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield() 方法只会给相同优先级或更高优先级的线程以运行的机会;
  2. 线程执行 sleep() 方法后转入阻塞(blocked)状态,而执行yield()方法后转入就绪(ready)状态;
  3. sleep()方法声明抛出 InterruptedException,而 yield() 方法没有任何声明任何异常。
  4. sleep() 方法比 yield() 方法(跟操作系统 CPU 调度相关)具有更好的可移植性。

4、当一个线程进入一个对象的 synchronized 方法 A 之后,其他线程是否可进入此对象的 synchronized 方法B?

不能。其他线程只能访问该对象的非同步方法,同步方法则不能进入。因此非静态方法上的 synchronized 修饰符要求执行方法时要获得对象的锁,如果已经进入A方法说明对象锁已经被取走,那么试图进入B 方法的线程就只能在等锁池(注意不是等待池哦)中等待对象的锁。

5、请说出与线程同步以及线程调用相关的方法。

  1. wait(): 使一个线程处于等待(阻塞)状态,并且释放所持有对象的锁;
  2. sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理 InterruptedException异常;
  3. notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由 JVM 确定唤醒哪个线程,而且与优先级无关;
  4. notifyAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态;

补充
Java 5 通过 Lock 接口提供了显式的锁机制(explicit lock),增强了灵活性以及对线程的协调。Lock 接口中定义了加锁(lock())和解锁(unlock())的方法,同时还提供了 newCondition() 方法来产生用于线程之间通信的 Condition 对象,此外, Java 5 还提供了信号量机制(semaphore),信号量可以用来限制对某个共享资源进行访问的线程的数量。在对资源进行访问之前,线程必须得到信号量的许可(调用 Semaphore对象的acquire()方法);在完成对资源的访问后,线程必须向信号量归还许可(调用 Semaphore 对象的 release() 方法)。

源链接-掘金

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值