object是java程序中所有的类的父类,换句话说,所有类继承了object类中的方法,所有类都具有object中的方法。
方法 | 备注 |
protected Object Clone() | 本地方法;根据已有对象为模板,新建一个对象; |
boolean equals(Object) | 默认为“==”比较,引用类型的数据就会比较是否引用了同一个对象;一般子类会重写这个方法; |
protected void finalize() | 当垃圾回收器要回收该对象时,会先调用此方法,但只会调用一次 |
Class<?> getClass() | 获取当前对象的class对象,每个类别加载后都会在堆上生成一个class对象,并把它当成访问类信息的入口 |
int hashCode() | 返回该对象的hash值 |
void notify() | |
void nitifyAll() | |
String toString() | 返回该对象的字符串显示 |
void wait() | |
void wait(long timeout) | |
void wait(long timeout,int namous) |
notify():唤醒一个正在等待该对象监视器的线程。如果多个线程都在等待该对象监视器,就会从它们中选择一个唤醒。这种选择是任意的。一个线程通过调用该对象的wait方法进入等待该对象监视器。被唤醒的线程并不会马上被执行,直到当前执行的线程放弃该对象的锁。被唤醒的线程将会和其他竞争该对象锁的线程进行竞争。例如,被唤醒的线程没有可靠的优势,即无法保证一定会成为下一个获得此对象锁的线程。这个方法应该被拥有该对象监视器的线程调用。一个线程想用成为该对象监视器的拥有者,需要通过以下三种方式:1).通过执行该对象的同步实例方法(锁为该方法所在的对象);2).通过执行使用该对象作为锁的同步代码块(同步代码块,可自定义一个对象为锁);3).对于class类型的对象,通过执行该类的同步静态方法(锁为该方法所在的类的class对象)。
notifyAll():唤醒所有等待该对象监视器的线程。一个线程通过调用该对象的wait方法,进入等待该对象监视器的队列。
wait():使当前线程进入等待该对象监视器的状态,直到其他线程调用该对象的notify()或者notifyAll()方法。换句话说,这个方法的行为和调用wait(0)相同。当前线程必须持有该对象监视器。这个线程释放了该对象监视器的拥有权,进入等待,直到其他线程调用notify()或者notifyAll()唤醒正在等待该对象监视器的线程。这个线程会等待直到它能重新获取对象监视器,然后恢复执行。因为在一个参数的版本中,中断和假的唤醒是可能的,所以这个方法应该总是在一个循环中执行:
* <pre>
* synchronized (obj) {//当前线程获取obj锁
* while (<condition does not hold(当前线程继续执行的条件不成立时)>)
* obj.wait();//当前线程释放锁
* ... // Perform action appropriate to condition
* }
* </pre>
这个方法应该被持有该对象监视器的线程调用。查看notify方法的介绍,可了解一个线程如何获取到对象监视器。
wait(long timeout):使当前线程等待,直到其他线程调用该对象的notify()方法或notifyAll()方法,或者等经过了一定(time out)的时间。当前线程必需持有该对象监视器。这个方法导致了当前线程将自己置于等待集合中,然后放弃了该对象监视器。出于线程调度的目的,线程T被禁用,并且休眠至一下四个事件中的其中一个发生为止:
1).其他线程调用了这个对象的notify方法,并且恰好选中这个线程来唤醒;
2).其他线程调用这个对象的notifyAll方法;
3).其他线程中,当前线程调用interrupt方法,这个需要当前线程的代码里进行配合,检测到interrupt标志位变化后,如何进行后续处理;
4).指定的等待时间用完,这个时间无法确定可能多,可能少。如果,timeout是0,那么线程就会去考虑时间是否用完,只是简单等待其他线程的唤醒。
上面四种事件任一件执行后,线程T会被从等待队列中移除,并且重新启用线程调度。它接着会和其他可执行状态线程竞争该对象监视器,一旦它获得了这个对象的控制权,它的所有对这个对象的同步请求都会恢复到原来的状态,即恢复到调用wait方法时的状态。线程T会从wait方法中返回。因此,在wait方法返回时,对象的同步状态会恢复到wait方法调用时的状态。
一个线程除了以上四种情况被唤醒外,还有可能被虚假唤醒。虽然,这在现实中很难发生,应用必须通过测试线程应该被唤醒的条件来防范它,如果这个条件没有达到,那么该线程将继续进入wait。换句话说,wait应该始终在循环里调用,像这样:
* <pre>
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait(timeout);
* ... // Perform action appropriate to condition
* }
* </pre>
如果当前线程是在阻塞状态中在其他线程中调用interrupted方法的,那么将会抛出InterruptedException。除非该线程恢复了wait前的状态,否则不可能抛出此异常。也就是说,该线程需要先退出阻塞状态,获取对象监视器后才能抛出此异常。
注意这个wait方法,因为它只是将当前线程放在了该对象的等待队列中,仅仅是结算次对象,但是当前线程可以同步的任何其他对象在线程等待时仍然被锁定。这里很可能会出现死锁。
这个方法只能被拥有该对象锁的线程调用。查看notify方法的介绍,就能清楚一个线程如何成为该对象监视器的拥有者。
notifyAll():这个方法和有一个参数的wait(long timeout)相似,当它能在放弃之前,对等待通知的时间进行更精细化控制。等待时间精确到了纳秒级别。其他方面,它和wait(long timeout)一样。特别是wait()=wait(0)=wait(0,0)。