目录
方法总结
clone()、equals(Object obj)、finalize()、getClass()、hashCode()、notify()、notifyAll()、toString()、wait()、wait(long timeout)、wait(long timeout, int nanos)
clone()
创建并返回此对象的一个副本。
1、x.clone() != x,返回true。
2、x.clone().getClass() == x.getClass(),返回true,非必须满足项。
3、x.clone().equals(x),返回true,非必须满足项。
Object 类本身不实现接口 Cloneable,所以在类为 Object 的对象上调用 clone 方法将会导致在运行时抛出异常。一个类如果想要被复制,那么该类必须实现Cloneable。
equals(Object obj)
指示其他某个对象是否与此对象“相等”。
- 自反性:对于任何非空引用值
x
,x.equals(x)
都应返回true
。 - 对称性:对于任何非空引用值
x
和y
,当且仅当y.equals(x)
返回true
时,x.equals(y)
才应返回true
。 - 传递性:对于任何非空引用值
x
、y
和z
,如果x.equals(y)
返回true
,并且y.equals(z)
返回true
,那么x.equals(z)
应返回true
。 - 一致性:对于任何非空引用值
x
和y
,多次调用 x.equals(y) 始终返回true
或始终返回false
,前提是对象上equals
比较中所用的信息没有被修改。 - 对于任何非空引用值
x
,x.equals(null)
都应返回false
。
对于任何非空引用值 x
和 y
,当且仅当 x
和 y
引用同一个对象时,此方法才返回 true
(x == y
具有值 true
)。
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
finalize()
1、当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。对于任何给定对象,Java 虚拟机最多只调用一次 finalize 方法。
2、finalize()是当垃圾回收器将要回收对象所占内存之前被调用,即当一个对象被虚拟机宣告死亡时会先调用它finalize()方法,让此对象处理它生前的最后事情(这个对象可以趁这个时机挣脱死亡的命运,但是不保证一定能摆脱)。
getClass()
返回此 Object
的运行时类。返回的 Class
对象是由所表示类的 static synchronized
方法锁定的对象。
hashCode()
返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable
提供的哈希表)的性能。
- 在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
- 如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用
hashCode
方法都必须生成相同的整数结果。 - 如果根据 equals(Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法不 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。
notify()
1、唤醒在此对象监视器上等待的单个线程。如果所有线程都在此对象上等待,则会选择唤醒其中一个线程。选择是任意性的,并在对实现做出决定时发生。线程通过调用其中一个 wait
方法,在对象的监视器上等待。
2、直到当前线程放弃此对象上的锁定,才能继续执行被唤醒的线程。也就是说,并不是唤醒就会去立刻执行!
3、通过以下三种方法之一,线程可以成为此对象监视器的所有者:
- 通过执行此对象的同步实例方法。
- 通过执行在此对象上进行同步的
synchronized
语句的正文。 - 对于
Class
类型的对象,可以通过执行该类的同步静态方法。
4、一次只能有一个线程拥有对象的监视器。
notifyAll()
唤醒在此对象监视器上等待的所有线程。线程通过调用其中一个 wait
方法,在对象的监视器上等待。
toString()
返回该对象的字符串表示。通常, toString
方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。
wait()
在其他线程调用此对象的notify()方法或者notifyAll()方法前,导致当前线程等待。
wait(long timeout)
在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。
wait(long timeout, int nanos)
在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量前,导致当前线程等待。(通俗的解释就是,这个wait方法等待的时间更精确- -!)
对监视器和锁的通俗解释
使用比较形象的说明,监视器就像一个包含一个特殊房间(对象实例)的建筑物,每次只能占用一个线程。这个房间通常包含一些需要防止并发访问的数据。从一个线程进入这个房间到它离开的时间,它可以独占访问房间中的任何数据。进入监控的建筑被称为“进入监控监视器。”进入建筑内部特殊的房间叫做“获取监视器”。房间占领被称为“拥有监视器”,离开房间被称为“释放监视器。”让整个建筑被称为“退出监视器。”
当一个线程访问受保护的数据(进入特殊的房间)时,它首先在建筑物接收(entry-set)中排队。如果没有其他线程在等待(拥有监视器),线程获取锁并继续执行受保护的代码。当线程完成执行时,它释放锁并退出大楼(退出监视器)。
如果当一个线程到达并且另一个线程已经拥有监视器时,它必须在接收队列中等待(entry-set)。当当前所有者退出监视器时,新到达的线程必须与在入口集中等待的其他线程竞争。只有一个线程能赢得竞争并拥有锁。