前言
在Thread类和Object类中有些多线程中常用的方法,本文主要记录一下相关方法及可能会问的面试题。如有不妥之处,敬请指正。
interrupted
中断可以理解为线程的一个标志位,它表示了一个运行中的线程是否被其他线程进行了中断操作。中断好比其他线程对该线程打了一个招呼。其他线程可以调用该线程的interrupt()方法对其进行中断操作,同时该线程可以调用isInterrupted()来感知其他线程对其自身的中断操作,从而做出响应。另外,同样可以调用Thread的静态方法interrupted()对当前线程进行中断操作,该方法会清除中断标志位。需要注意的是,当抛出InterruptedException时候,会清除中断标志位,也就是说在调用isInterrupted会返回false。
sleep()
sleep()方法是Thread的静态方法,在休眠时间达到后如果再次获得CPU时间片就会继续执行,如果当前线程获得了锁,sleep()方法只是会让出CPU并不会释放掉对象锁。
wait()
wait是Object实例方法,必须要在同步方法或者同步块中调用,也就是必须已经获得对象锁。会立即释放占有的对象锁,使得该线程进入等待池中,等待下一次获取资源。wait()方法必须等待Object.notift或Object.notifyAll通知后,才会离开等待池,并且再次获得CPU时间片才会继续执行。
为什么wait必须在同步代码块中?
wait/notify是线程之间的通信,他们存在竞态,我们必须保证在满足条件的情况下才进行wait。换句话说,如果不加锁的话,那么wait被调用的时候可能wait的条件已经不满足了(如上述)。由于错误的条件下进行了wait,那么就有可能永远不会被notify到,所以我们需要强制wait/notify在synchronized中。
join()
在一个线程中调用其他线程join()时,当前线程会进入等待状态,需要等被调用join()的线程执行完之后才可以继续执行。如下代码中thread 和 main线程的执行顺序和书否有join()有关。
public class Test {
public static void main(String[] args) {
ThreadTestJoin thread = new ThreadTestJoin();
thread.start();
try {
thread.join();
System.out.println("------------------");
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("Main thread is finished");
}
}
class ThreadTestJoin extends Thread{
public void run() {
try {
System.out.println(Thread.currentThread().getName()+"-->running");
Thread.sleep(10);
System.out.println(Thread.currentThread().getName()+"-->end");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
yield()
yield()是一个静态方法,一旦执行,它会使当前线程让出CPU,但是,需要注意的是,让出的CPU并不是代表当前线程不再运行了,如果在下一次竞争中,又获得了CPU时间片当前线程依然会继续运行。另外,让出的时间片只会分配给当前线程相同优先级的线程。
面试常问:wait()和sleep()的区别
1.来自不同的类,wai()t是object的方法,sleep()是Thread的静态方法;
2.锁的释放,wait()会释放锁,也就是说必须持有锁才能调用wait(),sleep()不会释放锁;
3.使用范围不同,wait()必须在同步代码块中使用,sleep()可以在任何地方使用;
此处插入一个网上找到的线程状态切换图,侵删。