Java面试题
1、Thread 类的 sleep()方法和对象的 wait()方法都可以让线程暂停执行,它们有什么区别?
sleep()方法(休眠)是线程类(Thread)的静态方法,调用此方法会让当前线程暂停执行指定的时间,将执行机会(CPU)让给其他线程,但是对象的锁依然保持,因此休眠时间结束后会自动恢复。wait()是 Object 类的方法,调用对象的 wait()方法导致当前线程放弃对象的锁(线程暂停执行),进入对象的等待池(wait pool),只有调用对象的 notify()方法(或 notifyAll()方法)时才能唤醒等待池中的线程进入等锁池(lock pool),如果线程重新获得对象的锁就可以进入就绪状态。
2、线程的 sleep()方法和 yield()方法有什么区别
- sleep()方法给其他线程运行机会时不考虑线程的优先级,因此会给低优先级的线程以运行的机会;yield()方法只会给相同优先级或更高优先级的线程以运行的机会;
- 线程执行 sleep()方法后转入阻塞(blocked)状态,而执行 yield()方法后转入就绪(ready)状态;
- sleep()方法声明抛出 InterruptedException,而 yield()方法没有声明任何异常;
- sleep()方法比 yield()方法(跟操作系统 CPU 调度相关)具有更好的可移植性。
3、当一个线程进入一个对象的 synchronized 方法 A 之后,其它线程是否可进入此对象的 synchronized 方法 B
不能。其它线程只能访问该对象的非同步方法,同步方法则不能进入。因为非静态方法上的 synchronized 修饰符要求执行方法时要获得对象的锁,如果已经进入A 方法说明对象锁已经被取走,那么试图进入 B 方法的线程就只能在等锁池(注意不是等待池哦)中等待对象的锁。
4、请说出与线程同步以及线程调度相关的方法
- wait():使一个线程处于等待(阻塞)状态,并且释放所持有的对象的锁;
- sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要处理 InterruptedException 异常;
- notify():唤醒一个处于等待状态的线程,当然在调用此方法的时候,并不能确切的唤醒某一个等待状态的线程,而是由 JVM 确定唤醒哪个线程,而且与优先级无关;
- notityAll():唤醒所有处于等待状态的线程,该方法并不是将对象的锁给所有线程,而是让它们竞争,只有获得锁的线程才能进入就绪状态;
5、synchronized 关键字的用法
synchronized 关键字可以将对象或者方法标记为同步,以实现对对象和方法的互斥访问,可以用 synchronized(对象) { … }定义同步代码块,或者在声明方法时将 synchronized 作为方法的修饰符。