几种方法的解释
Thread类中的方法
1、yield
该方法向线程调度器提示,当前线程(调用该方法的线程对象代表的线程)愿意让出处理器的使用权,但是线程调度器可能会忽视该提示。很少有适合使用该方法的地方。它可能在调试或者测试的时候,帮助重现由于竞争条件出现的bug。它还可能在设计并发控制结构的时候提供帮助,比如java.util.concurrent.locks包中的一些类。
2、sleep
该方法会让当前线程(调用该方法的线程对象代表的线程)睡眠指定的一段时间(暂时停止执行),但当前线程不会失去锁的拥有权(还会继续占用锁)。上述两个方法只是指定的睡眠时间精度不同。
3、start
该方法会让当前线程(调用该方法的线程对象代表的线程)开始执行。JVM虚拟机会调用该线程的run()方法。对一个线程只能start()一次。
对同一个线程多次调用start()会抛出异常:java.lang.IllegalThreadStateException,即当前状态(start)不能调用start()方法。
但是可以多次调用线程的run()方法!
4、join
该方法会让当前线程(调用该方法的线程,注意,这里并不是thread.join()
中thread所表示的线程,而是方法thread.join()
所在的线程)等待指定时间(如果为0,表示一直等到thread执行完),让join()方法的所属线程thread执行。
join()方法内部是调用wait()方法实现的。
Object类中的方法
1、wait
该方法会让当前线程(该方法调用所在的线程)进入等待状态,直到被该对象(wait()
方法的this
对象)的notify()
或者notifyAll()
唤醒,或者等待时间结束(wait(long timeout)
中的timeout
结束)。
当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,同时会释放对象的锁(暂时,wait(long timeout)超时时间到后还需要返还对象锁),此时其他线程可以访问该对象;这里隐含了一个条件就是:wait()方法只应该被拥有对象monitor的线程调用,即wiat()必须放在synchronized同步块中,否则会在抛出java.lang.IllegalMonitorStateException
异常。
如果发生下面的4种事件中的任意一件,该线程就会从该对象的等待集中移除,重新加入线程调度。此后,它就会和其他线程一样去争夺该对象的锁,一旦获取了该对象的控制权,所有该对象的同步声明就会重新加载。
其他线程触发了该对象的notify方法,那么该线程就可能会被唤醒(并不一定会唤醒,可能很多线程都wait该对象);
其他线程触发了notifyAll方法;
被其他线程中断(interrupt()方法)
设定的等待时间已到。如果是
wait(0)
或者wait()
则会一直等待直到唤醒。
正确使用wait()的方式如下:(等待应该总是发生在轮询中:waits should always occur in loops
)
如果当前线程在等待之前或者等待期间被其他线程打断(Thread.interrupt()),就会抛出InterruptedException异常。
2、notify
notify()
唤醒等待该对象monitor的单个线程。如果多个线程都在等待该对象monitor,那么被唤醒的线程是不固定的、任意的。被唤醒的线程并不会立即执行,而是等到当前线程放弃了该对象的锁。被唤醒的线程会和其他线程去竞争对该对象的同步操作。也就是说,被唤醒的线程仅仅是被唤醒去参与竞争,并不是唤醒了就开始执行。
该方法只应该被该对象的monitor的所有者线程调用。一个线程成为该对象的monitor的所有者有以下三种途径:
①执行该对象的同步的实例方法
②执行一个同步块,并且该同步了该对象
③对Class类型的对象,执行该类的一个同步的静态方法
常见问题
1、sleep和wait的区别
sleep是Thread类的方法,wait是Object类的方法;
sleep只是让线程休眠,与锁机制无关,不会释放锁(假如已经拥有锁),而wait则会让所在线程放弃锁。
wait和sleep都可以通过interrupt方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException
Last updated