线程的基本操作(二)
等待和通知(wait & notify)
这两个方法并不是在Thread类中的,而是输出Object类,这也意味着任何对象都可以调用这两个方法。当一个线程调用obj.wait()后,该线程就会进入obj对象的等待队列,当obj.notify()被调用时,它就会从这个等待队列中随机唤醒一个线程。
notifyAll()方法会将等待队列中的所有线程都唤醒。
obj.wait()方法必须包含在相应的sychronized块中。
在线程A中,obj.wait()方法在执行前需要先获得目标对象obj的监视器,wait()方法执行完后会释放这个监视器,同样地,在线程B中,通过obj.notify()唤醒线程A(或其他等待队列中的线程)时,需要先获得obj的监视器(obj.wait()释放的那个),obj.notify()执行完后释放监视器,被唤醒的线程A仍然需要先获得obj监视器,才能继续往下执行。
Object.wait()和Thread.sleep() 都可以使线程等待一段时间,wait()可以被唤醒并且释放对象锁,sleep()不会释放任何资源。
挂起和继续执行(suspend & resume)
这两个方法是被废弃的方法,不建议使用。因为线程在suspend()后不会释放任何锁资源,其他想要访问被它占用的锁的时候会被牵连,无法正常运行,就好比一辆车停在了路口,其他车也无法同行
更重要的是,如果resume()意外地在suspend之前就执行了,线程一直阻塞,所占用的锁将永远不会释放,并且线程的状态是Runnable,这将影响我们对系统当前状态的判断。
等待线程结束和谦让(join & yield)
t1.join()会使当前线程一直阻塞,直到t1线程执行完毕;t1.join(1000)会使线程等待1s。
join()的本质是让调用线程wait()在当前线程的实例对象上,jdk中join()的核心代码
while(isAlive()){
wait(0);
}
例如在main函数中调用t1.join(),当t1执行完之后退出之前,会调用notifyAll()通知所有等待线程”可以继续执行了“。
注意:不要在应用程序中,在Thread对象实例上使用类似wait()和notify()方法,因为这可能会影响系统API工作或被影响。
-----------------------------------------------------《实战Java高并发设计》笔记------------------------------------------------------