学习过Java的程序猿们都知道,Object是Java所有类的顶级父类,所有的类都继承自该类,包括数组都实现了该类中的方法。在Object的源码中也是这么写道 (tips:学习源码的过程,也是提升英语阅读能力的过程,本人会做该标注来表示某个词组的意思【外文】(译文)):
/**
* Class {@code Object} is the root of [the class hierarchy](类层次结构). Every class
*
* Object类是类层次结构的根
*
* has {@code Object} as a superclass. All objects, including arrays, implement
* the methods of this class.
*
* Object类是所有类的超类, 即父类, 包括数组都是实现了该类的方法
*
* @author unascribed
* @see java.lang.Class
* @since JDK1.0
*/
public class Object {
接下来将逐个分析源码中的方法。
1、private static native void registerNatives ()
也许你在阅读源码的时候,会看到一些类 (如System类、Class类、ClassLoader类、Unsafe类等) 的开头会有一个这样的静态变量和静态代码块:
private static native void registerNatives(); // native修饰的本地方法
static {
registerNatives(); // 注册本地方法
}
众所周知,Java有两种方法:本地方法和Java方法,其中:Java方法由Java语言编写,编译成字节码,然后存储在class文件中;本地方法由其他语言编写,存储在动态链接库中,本地方法是联系Java程序和底层主机操作系统的方法。
运行中的Java程序在调用本地方法时,JVM会装载包含这个本地方法的库,并调动该方法。调用native方法的过程如下:
(1):通过System.loadLibrary ()
方法将包含本地方法的动态文件加载进内存;
(2):当Java方法调用native方法时,JVM在加载的动态文件中定位并链接本地方法,从而执行本地方法。
registerNatives()
方法本质是一个native方法,但却不同于一般的native方法,当包含registerNatives()
方法的类被加载的时候,调用该方法实现对类中其他的native方法的注册。如Object类中有native方法:hashCode()
、getClass()
、clone()
等,该方法会在Object类被加载的时候注册。
但是,为什么要注册呢?上文讲到,调用native方法需要经过两个步骤,而registerNatives()
方法的作用就是取代第二步,让程序主动将native方法链接到调用方。当Java程序需要调用native方法时,可以直接调用,而不需要JVM再去定位并链接。
总结使用registerNatives () 方法的好处:
(1):通过registerNatives()
方法在类被加载的时候,主动将本地方法链接到调用方,比JVM定位并链接本地方法的效率更高;
(2):若本地方法在程序运行中更新了,可以通过registerNatives()
方法进行更新;
(3):Java程序需要调用一个本地应用提供的方法时,因为JVM只会检索本地动态库,因而无法定位到要调用的本地方法,而使用registerNatives()
方法可进行主动链接。
2、public final native Class<?> getClass():返回当前对象的运行时类
源码如下:
/**
* Returns the runtime class of this {@code Object}. The returned {@code Class}
* object is the object that is locked by {@code
* static synchronized} methods of the represented class.
*
* 返回此Object的运行时类。返回的Class对象是由所表示类的static synchronized方法锁定的对象。
*
* <p>
* <b>The actual result type is {@code Class<? extends |X|>} where {@code |X|}
* is the erasure of the static type of the expression on which {@code getClass}
* is called.</b> For example, no cast is required in this code fragment:
* </p>
*
* 实际结果类型是 Class<? extends |X|>,其中|X|表示擦除表达式中的静态类型,
* 该表达式调用getClass ()方法。例如,以下代码不需要强制类型转换
*
* <p>
* {@code Number n = 0; }<br>
* {@code Class<? extends Number> c = n.getClass(); }
* </p>
*
* @return The {@code Class} object that represents the runtime class of this
* object.
* @jls 15.8.2 Class Literals
*/
public final native Class<?> getClass();
假设存在下述两个类TestOne和TestTwo:
public class TestTwo {
static {
System.out.println("TestTwo被初始化了!!");
}
public void printMsg() {
System.out.println("TestTwo类的printMsg()方法被执行了!!");
}
}
public class TestOne {
static {
System.out.println("TestOne被初始化了!!");
}
public void testClass() {
this.getClass();
}
public void printMsg() {
System.out.println("TestOne类的printMsg()方法被执行了!!");
}
public static void main(String[] args) {
TestOne t = new TestOne();
t.testClass();
}
}
执行结果如下:
TestOne被初始化了!!
这说明在调用一个对象的getClass()
方法时会初始化该类的静态代码块。而testClass()
方法中的this指代的是Object对象,可通过如下验证,重新改造TestOne类。
public class TestOne {
static {
System.out.println("TestOne被初始化了!!");
}
public void testClass() throws Exception{
Object o = this.getClass().newInstance();
if(o instanceof TestOne) {
System.out.println("o是Object类的实例!!");
TestOne t = (TestOne) o;
t.printMsg();
}
}
public void printMsg() {
System.out.println("TestOne类的printMsg()方法被执行了!!");
}
public static void main(String[] args) throws Exception{
TestOne t = new TestOne();
t.testClass();
}
}
输出结果是:
TestOne被初始化了!!
o是Object类的实例!!
TestOne类的printMsg()方法被执行了!!
结果说明:this指代Object对象。此外,通过Object o = this.getClass().newInstance();
先得到一个Class对象,然后通过该Class对象的方法newInstance()
得到一个TestOne类的对象。该Class对象和TestOne对象不同,在API中所说的返回运行时类的Class对象,指的就是当前运行这个类的Class对象。
在Class类中存在一个静态方法forName("指定类名")
,该方法能够实现和getClass()
方法一样的功能,即返回运行时的Class对象。不同的是,指定的类名必须是全限定名,且该方法有个重载方法。如下所示:
// 下面两行代码实现的功能相同,都是返回运行时Class对象
this.getClass();
Class.forName("test.TestOne");
// forName()的重载方法
// 第一个参数:类的全限定名;
// 第二个参数:是否初始化该类,即是否执行static代码块;
// 第三个参数:指定类加载器
Class.forName("test.TestOne", false, this.getClass().getClassLoader());
3、public native int hashCode():返回一个由当前对象的内部地址转换而来的哈希值
源码如下:
/**
* Returns a hash code value for the object. This method is supported for the
* benefit of hash tables such as those provided by {@link java.util.HashMap}.
* <p>
* The general contract of {@code hashCode} is:
* <ul>
* <li>Whenever it is invoked(调用) on the same object more than once during an
* execution of a Java application, the {@code hashCode} method must
* consistently return the same integer, provided(倘若) no information used in
* {@code equals} comparisons on the object is modified. This integer need not
* remain consistent from one execution of an application to another execution
* of the same application.
* <li>If two objects are equal according to the {@code equals(Object)} method,
* then calling the {@code hashCode} method on each of the two objects must
* produce the same integer result.
*
* hashcode相等,equals不一定会相等;
* 而equals相等,则两个对象的hashcode相等的
*
* <li>It is <em>not</em> required that if two objects are unequal according to
* the {@link java.lang.Object#equals(java.lang.Object)} method, then calling
* the {@code hashCode} method on each of the two objects must produce distinct
* integer results. However, the programmer should be aware that producing
* distinct integer results for unequal objects may improve the performance of
* hash tables.
* </ul>
* <p>
* As much as is reasonably practical, the hashCode method defined by class
* {@code Object} does return distinct integers for distinct objects. (This is
* typically implemented by converting the internal address of the object into
* an integer, but this implementation technique is not required by the
* Java™ programming language.)
*
* @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object)
* @see java.lang.System#identityHashCode
*/
public native int hashCode();
根据源码,可以得出如下结论:
(1):在Java应用的一次执行过程中,无论该方法调用多少次,返回的值保持不变。
(2):若存在两个对象obj1和obj2,若obj1.equals(obj2)
返回true
,则这两个对象调用hashCode()
方法返回的值一样。反之,则不一定成立,即obj1.hashCode() == obj2.hashCode()
返回true
,但obj1.equals(obj2)
不一定返回true
。
(3):若obj1.equals(obj2)
返回false
,则obj1和obj2的hashCode()
有可能相等。但为obj1.equals(obj2)
返回false
的两个对象设置不同的hashCode()
在一定程度上能提高系统性能。
public static void main(String[] args) {
String str1 = "通话";
String str2 = "重地";
System.out.println(String.format("str1:%d | str2:%d", str1.hashCode(), str2.hashCode()));
System.out.println(str1.equals(str2));
}
返回结果:
str1:1179395 | str2:1179395
false
4、public boolean equals(Object obj)
源码如下:
/**
* Indicates whether some other object is "equal to" this one.
*
* 指示其他对象是否“等于”该对象
*
* <p>
* The {@code equals} method implements an equivalence relation on non-null
* object references:
* <ul>
* <li>It is <i>reflexive</i>: for any non-null reference value {@code x},
* {@code x.equals(x)} should return {@code true}.
* <li>It is <i>symmetric</i>: for any non-null reference values {@code x} and
* {@code y}, {@code x.equals(y)} should return {@code true} if and only if
* {@code y.equals(x)} returns {@code true}.
* <li>It is <i>transitive</i>: for any non-null reference values {@code x},
* {@code y}, and {@code z}, if {@code x.equals(y)} returns {@code true} and
* {@code y.equals(z)} returns {@code true}, then {@code x.equals(z)} should
* return {@code true}.
*
* equals()的比较具有传递性
*
* <li>It is <i>consistent</i>: for any non-null reference values {@code x} and
* {@code y}, multiple invocations(调用) of {@code x.equals(y)} consistently
* return {@code true} or consistently return {@code false}, provided no
* information used in {@code equals} comparisons on the objects is modified.
* <li>For any non-null reference value {@code x}, {@code x.equals(null)} should
* return {@code false}.
*
* 任何一个非null对象与null进行equals, 都返回false
*
* </ul>
* <p>
* The {@code equals} method for class {@code Object} implements the most
* discriminating possible equivalence relation on objects; that is, for any
* non-null reference values {@code x} and {@code y}, this method returns
* {@code true} if and only if {@code x} and {@code y} refer to the same object
* ({@code x == y} has the value {@code true}).
* <p>
* Note that it is generally necessary to override the {@code hashCode} method
* whenever this method is overridden, so as to maintain the general contract
* for the {@code hashCode} method, which states that equal objects must have
* equal hash codes.
*
* equals相等的对象必须具有相同的hashcode
*
* @param obj
* the reference object with which to compare.
* @return {@code true} if this object is the same as the obj argument;
* {@code false} otherwise.
* @see #hashCode()
* @see java.util.HashMap
*/
public boolean equals(Object obj) {
return (this == obj);// equals的本质是 "=="
}
根据源码可知:equals()
方法的本质是双等号 ==
,且任意一个非null对象和null进行equals()
时,返回false
。
我们知道的是,双等号 ==
对于基本数据类型是值比较,而对于引用数据类型是引用比较。而equals()
默认情况下是引用比较,只是很多类对该方法进行了重写,如String、Integer等将其改造成值比较。所以,equals()
一般情况下是值比较。
5、protected native Object clone()
源码如下:
/**
* Creates and returns a copy of this object. The precise meaning of "copy" may
* depend on the class of the object. The general intent is that, for any object
* {@code x}, the expression: <blockquote>
*
* <pre>
* x.clone() != x
* </pre>
*
* </blockquote> will be true, and that the expression: <blockquote>
*
* <pre>
* x.clone().getClass() == x.getClass()
* </pre>
*
* </blockquote> will be {@code true}, but these are not absolute requirements.
* While it is typically the case that(通常情况下): <blockquote>
*
* <pre>
* x.clone().equals(x)
* </pre>
*
* </blockquote> will be {@code true}, this is not an absolute requirement.
* <p>
* By convention(按照惯例), the returned object should be obtained by calling
* {@code super.clone}. If a class and all of its superclasses (except
* {@code Object}) obey this convention, it will be the case that
* {@code x.clone().getClass() == x.getClass()}.
* <p>
* By convention, the object returned by this method should be independent of
* this object (which is being cloned). To achieve this independence, it may be
* necessary to modify one or more fields of the object returned by
* {@code super.clone} before returning it. Typically, this means copying any
* mutable(可变的) objects that comprise(包括) the internal "deep structure" of the
* object being cloned and replacing the references to these objects with
* references to the copies. If a class contains only primitive fields or
* references to immutable(不变的) objects, then it is usually the case that no
* fields in the object returned by {@code super.clone} need to be modified.
*
* 按照惯例,此方法返回的对象应独立于该对象(将被克隆)。
* 为了实现这种独立性,可能有必要在返回之前修改{@code super.clone}返回的对象的一个或多个字段。
* 通常,这意味着复制包含要克隆的对象的内部“深层结构”的任何可变对象,并将对这些对象的引用替换为对副本的引用。
* 如果一个类仅包含原始字段或对不可变对象的引用,
* 则通常情况下,{@ code super.clone}返回的对象中的任何字段都无需修改。
*
* <p>
* The method {@code clone} for class {@code Object} performs a specific cloning
* operation. First, if the class of this object does not implement the
* interface {@code Cloneable}, then a {@code CloneNotSupportedException} is
* thrown. Note that all arrays are considered(被视为) to implement the interface
* {@code Cloneable} and that the return type of the {@code clone} method of an
* array type {@code T[]} is {@code T[]} where T is any reference or primitive
* type. Otherwise, this method creates a new instance of the class of this
* object and initializes all its fields with exactly the contents of the
* corresponding fields of this object, as if by assignment(赋值); the contents of
* the fields are not themselves cloned. Thus, this method performs a "shallow
* copy" of this object, not a "deep copy" operation.
*
* 类{@code Object}的方法{@code clone}执行特定的克隆操作。
* 首先,如果此对象的类未实现接口{@code Cloneable},则将引发{@code CloneNotSupportedException}。
* 请注意,所有数组都被认为可以实现接口{@code Cloneable},
* 并且数组类型{@code T []}的{@code clone}方法的返回类型为{@code T [ ]},其中T是任何引用或原始类型。
* 否则,此方法将创建此对象的类的新实例,并使用该对象相应字段的内容完全初始化其所有字段,就像通过赋值一样;
* 字段的内容本身不会被克隆。 因此,此方法执行此对象的“浅复制”,而不是“深复制”操作。
*
* [clone方法执行的是复制,而不是深复制]
*
* <p>
* The class {@code Object} does not itself implement the interface
* {@code Cloneable}, so calling the {@code clone} method on an object whose
* class is {@code Object} will result in throwing an exception at run time.
*
* [Object类没有实现Cloneable接口,因此,在类为Object的对象上调用clone()方法时,运行时会出现异常]
*
* @return a clone of this instance.
* @throws CloneNotSupportedException
* if the object's class does not support the {@code Cloneable}
* interface. Subclasses that override the {@code clone} method can
* also throw this exception to indicate that an instance cannot be
* cloned.
* @see java.lang.Cloneable
*/
protected native Object clone() throws CloneNotSupportedException;
从源码可得出如下结论:
a) clone()
方法实现的是浅复制。如果实现Cloneable
接口的类存在可变对象(即引用数据类型),则该可变对象也要实现克隆,因为clone()
方法实现的只是一个直接赋值的操作,而对可变对象的赋值操作,仅是复制了一个引用地址的副本。
b) 数组类型是默认实现了Cloneable
接口。
c) 对于复杂的组合类的复制,建议使用序列化和反序列化的方式实现,在“实现数组复制常用的5种方式及组合类的深复制(深拷贝)”一文中有讲过。
x.clone() != x // true
x.clone().getClass() == x.getClass() // true
x.clone().equals(x) // true
6、public String toString()
/**
* Returns a string representation of the object. In general, the
* {@code toString} method returns a string that "textually represents(以文本形式表示)"
* this object. The result should be a concise(简洁) but informative
* representation that is easy for a person to read. It is recommended that all
* subclasses override this method.
* <p>
* The {@code toString} method for class {@code Object} returns a string
* consisting of the name of the class of which the object is an instance, the
* at-sign character `{@code @}', and the unsigned hexadecimal(无符号十六进制)
* representation of the hash code of the object. In other words, this method
* returns a string equal to the value of: <blockquote>
*
* <pre>
* getClass().getName() + '@' + Integer.toHexString(hashCode())
* </pre>
*
* </blockquote>
*
* @return a string representation of the object.
*/
public String toString() {
// 该方法默认返回该类的全限定名 和 无符号十六进制的hashcode
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
若类没有重写toString()方法,该方法默认返回类的全限定名 + 无符号的十六进制数,即:getClass().getName() + “@” + Integer.toHexString(hashCode());
7、public final native void notify() 和 public final native void notifyAll();
/**
* Wakes up a single thread that is waiting on this object's monitor(对象监视器). If
* any(任何) threads are waiting on this object, one of them is chosen to be
* awakened. The choice is arbitrary(任意的) and occurs at the discretion of the
* implementation (根据实现情况进行选择). A thread waits on an object's monitor by calling
* one of the {@code wait} methods.
* <p>
* The awakened thread will not be able to proceed until the current thread
* relinquishes(放弃) the lock on this object. The awakened thread will compete in
* the usual manner with any other threads that might be actively(主动) competing
* to synchronize on this object; for example, the awakened thread enjoys no
* reliable privilege or disadvantage in being [the next thread to lock this
* object].
* <p>
* This method should only be called by a thread that is the owner of this
* object's monitor. A thread becomes the owner of the object's monitor in one
* of three ways:
* <ul>
* <li>By executing a synchronized instance method of that object.
* <li>By executing the body of a {@code synchronized} statement that
* synchronizes on the object.
* <li>For objects of type {@code Class,} by executing a synchronized static
* method of that class.
* </ul>
* <p>
* Only one thread at a time can own an object's monitor.
*
* @throws IllegalMonitorStateException
* if the current thread is not the owner of this object's monitor.
* @see java.lang.Object#notifyAll()
* @see java.lang.Object#wait()
*/
public final native void notify();
/**
* Wakes up all threads that are waiting on this object's monitor. A thread
* waits on an object's monitor by calling one of the {@code wait} methods.
* <p>
* The awakened threads will not be able to proceed until the current thread
* relinquishes the lock on this object. The awakened threads will compete in
* the usual manner with any other threads that might be actively competing to
* synchronize on this object; for example, the awakened threads enjoy no
* reliable privilege or disadvantage in being the next thread to lock this
* object.
* <p>
* This method should only be called by a thread that is the owner of this
* object's monitor. See the {@code notify} method for a description of the ways
* in which a thread can become the owner of a monitor.
*
* @throws IllegalMonitorStateException
* if the current thread is not the owner of this object's monitor.
* @see java.lang.Object#notify()
* @see java.lang.Object#wait()
*/
public final native void notifyAll();
如果有线程在等待某个对象的监视器,则随机唤醒一个notify()
(或全部notifyAll()
)等待对象监视器的线程;
一个对象被唤醒之后,不能马上得到该对象监视器,必须等待当前线程执行完,并释放该对象监视器;如果此时正好有其他线程主动获取该对象监视器,则被唤醒的线程需要跟该主动获取的线程竞争对象监视器;
notify()
或notifyAll()
方法只能由持有该对象监视器的线程调用,获取对象监视器有三种方法:
1)执行synchronized修饰的实例方法;
2)执行对象中由synchronized修饰的代码块;
3)对于类型为Class的对象,执行该类的synchronized static修饰的方法;任何时候,对象监视器只能由一个线程持有;
8、wait()方法的几种重载形式
/**
* Causes the current thread to wait until either another thread invokes the
* {@link java.lang.Object#notify()} method or the
* {@link java.lang.Object#notifyAll()} method for this object, or a specified
* amount of time has elapsed(过去).
* <p>
* The current thread must own this object's monitor.
* <p>
* [一个线程调用了wait()方法,会放弃该线程锁拥有的全部对象锁] This method causes the current thread (call
* it <var>T</var>) to place itself in the wait set(等待集) for this object and
* then to relinquish any and all synchronization claims on this object. Thread
* <var>T</var> becomes disabled for thread scheduling purposes[出于线程调度目的] and
* lies dormant(休眠) until one of four things happens:
* <ul>
* <li>Some other thread invokes the {@code notify} method for this object and
* thread <var>T</var> happens to be arbitrarily chosen as the thread to be
* awakened.
* <li>Some other thread invokes the {@code notifyAll} method for this object.
* <li>Some other thread {@linkplain Thread#interrupt() interrupts[中断]} thread
* <var>T</var>.
* <li>The specified amount of real time has elapsed, more or less(或多或少). If
* {@code timeout} is zero, however, then real time is not taken into
* consideration and the thread simply waits until notified. wait(0)无限阻塞,直到有线程唤醒
* </ul>
* The thread <var>T</var> is then removed from the wait set for this object and
* re-enabled for thread scheduling. It then competes in the usual manner with
* other threads for the right(权利) to synchronize on the object; once it has
* gained control of the object, all its synchronization claims on the object
* are restored(恢复) to the status quo ante - that is, to the situation as of the
* time that the {@code wait} method was invoked. Thread <var>T</var> then
* returns from the invocation of the {@code wait} method. Thus, on return from
* the {@code wait} method, the synchronization state [of the object] and [of
* thread] {@code T} is [exactly as](完全一样) it was when the {@code wait} method
* was invoked.
* <p>
* A thread can also wake up without being notified, interrupted, or timing
* out,[打断或等待超时实现的虚假唤醒] a so-called <i>spurious(伪 or 虚假) wakeup</i>. While this
* will rarely occur in practice, applications must [guard against](防范) it by
* testing for the condition that should have caused the thread to be awakened,
* and continuing to wait if the condition is not satisfied. In other words,
* waits should always occur [in loops](循环), like this one:
*
* <pre>
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait(timeout);
* ... // Perform action appropriate to condition
* }
* </pre>
*
* (For more information on this topic, see Section 3.2.3 in Doug Lea's
* "Concurrent Programming in Java (Second Edition)" (Addison-Wesley, 2000), or
* Item 50 in Joshua Bloch's "Effective Java Programming Language Guide"
* (Addison-Wesley, 2001).
*
* <p>
* If the current thread is {@linkplain java.lang.Thread#interrupt()
* interrupted} by any thread before or while it is waiting, then an
* {@code InterruptedException} is thrown. This exception is not thrown until
* the lock status of this object has been restored [as described above](如上所述).
* [如果一个线程处在waiting状态,此时任意一个线程调用该线程的interrupt()方法会抛出InterruptException异常]
* <p>
* Note that the {@code wait} method, as it places the current thread into the
* wait set for this object, unlocks only this object; any other objects [on
* which the current thread may be synchronized] remain locked while the thread
* waits.
* <p>
* This method should only be called by a thread that is the owner of this
* object's monitor. See the {@code notify} method for a description of the ways
* in which a thread can become the owner of a monitor.
*
* @param timeout
* the maximum time to wait in milliseconds.
* @throws IllegalArgumentException
* if the value of timeout is negative.
* @throws IllegalMonitorStateException
* if the current thread is not the owner of the object's monitor.
* @throws InterruptedException
* if any thread interrupted the current thread before or while the
* current thread was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when this exception
* is thrown.
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
public final native void wait(long timeout) throws InterruptedException;
/**
* Causes the current thread to wait until another thread invokes the
* {@link java.lang.Object#notify()} method or the
* {@link java.lang.Object#notifyAll()} method for this object, or some other
* thread interrupts the current thread, or a certain amount of real time has
* elapsed.
* <p>
* This method is similar to the {@code wait} method of one argument, but it
* allows finer control over the amount of time to wait for a notification
* before giving up. The amount of real time, measured in nanoseconds(纳秒), is
* given by: <blockquote>
*
* <pre>
* 1000000 * timeout + nanos
* </pre>
*
* </blockquote>
* <p>
* In all other respects, this method does the same thing as the method
* {@link #wait(long)} of one argument. In particular, {@code wait(0, 0)} means
* the same thing as {@code wait(0)}. [wait(0) 即 wait(0,0)]
* <p>
* The current thread must own this object's monitor. The thread releases
* [调用wait()方法,释放该线程所有的对象监视器] ownership of this monitor and waits until either
* of the following two conditions has occurred:
* <ul>
* <li>Another thread notifies threads waiting on this object's monitor to wake
* up either through a call to the {@code notify} method or the
* {@code notifyAll} method.
* <li>The timeout period, specified by {@code timeout} milliseconds plus
* {@code nanos} nanoseconds arguments, has elapsed.
* </ul>
* <p>
* The thread then waits until it can re-obtain ownership of the monitor and
* resumes execution.
* <p>
* As in the one argument version, interrupts and spurious wakeups are possible,
* [同样存在虚假唤醒] and this method should always be used in a loop:
*
* <pre>
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait(timeout, nanos);
* ... // Perform action appropriate to condition
* }
* </pre>
*
* This method should only be called by a thread that is the owner of this
* object's monitor. See the {@code notify} method for a description of the ways
* in which a thread can become the owner of a monitor.
*
* @param timeout
* the maximum time to wait in milliseconds.
* @param nanos
* additional time, in nanoseconds range 0-999999.
* @throws IllegalArgumentException
* if the value of timeout is negative or the value of nanos is not
* in the range 0-999999.
* @throws IllegalMonitorStateException
* if the current thread is not the owner of this object's monitor.
* @throws InterruptedException
* if any thread interrupted the current thread before or while the
* current thread was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when this exception
* is thrown.
*/
public final void wait(long timeout, int nanos) throws InterruptedException {
// final类型的方法,不可重写, 最后调用wait(timeout)方法
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException("nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
/**
* Causes the current thread to wait until another thread invokes the
* {@link java.lang.Object#notify()} method or the
* {@link java.lang.Object#notifyAll()} method for this object. In other words,
* this method behaves exactly as if it simply performs the call
* {@code wait(0)}.
* <p>
* The current thread must own this object's monitor. The thread releases
* ownership of this monitor and waits until another thread notifies threads
* waiting on this object's monitor to wake up [either] through a call to the
* {@code notify} method [or] the {@code notifyAll} method. The thread then
* waits until it can re-obtain ownership of the monitor and resumes execution.
* <p>
* As in the one argument version, interrupts and spurious wakeups are possible,
* and this method should always be used in a loop:
*
* <pre>
* synchronized (obj) {
* while (<condition does not hold>)
* obj.wait();
* ... // Perform action appropriate to condition
* }
* </pre>
*
* This method should only be called by a thread that is the owner of this
* object's monitor. See the {@code notify} method for a description of the ways
* in which a thread can become the owner of a monitor.
*
* @throws IllegalMonitorStateException
* if the current thread is not the owner of the object's monitor.
* @throws InterruptedException
* if any thread interrupted the current thread before or while the
* current thread was waiting for a notification. The <i>interrupted
* status</i> of the current thread is cleared when this exception
* is thrown.
* @see java.lang.Object#notify()
* @see java.lang.Object#notifyAll()
*/
public final void wait() throws InterruptedException {
wait(0);
}
根据上述三个方法的源码,可得出如下结论:
a) 一个线程调用了wait()
方法,会释放该线程持有的所有对象监视器;
b) 通过以下四种方式可唤醒线程:
1)线程恰好被调用notify()方法的线程唤醒;
2)有线程调用notifyAll() 方法;
3)阻塞时间过去,线程可以被重新调度;
4)其他线程interrupts()该阻塞线程;
c) wait(0)
即无限阻塞,直到被唤醒;与sleep(0)不同,sleep(0
)只是触发一次线程调度。
d) 一个线程被唤醒,会回到调用wait ()方法前的状态;
e) interrupted
和timing out
会导致伪唤醒 (即虚假唤醒),因此,当当前条件不能够满足唤醒时,该线程应一直阻塞下去,线程阻塞应放在循环中,即;
synchronized (obj){
while (condition does not hold) {
obj.wait (timeout);
}
}
f) 如果一个线程处于waiting状态,则任何一个线程调用阻塞线程的interrupt()方法会导致抛出InterruptException ()异常;
g) wait()
方法的本质是是执行wait(0)
,陷入无限阻塞;此外,wait(0, 0)
的等效于wait(0)
。
9、protected void finalize() throws Throwable
源码如下:
/**
* Called by the garbage collector on an object when garbage collection
* [finalize()方法被垃圾收集器用于清除不再被引用的对象] determines that there are no more references
* to the object. A subclass overrides the {@code finalize} method to dispose of
* system resources or to [处理系统资源或执行其他清除操作] perform other cleanup.
* <p>
* The general contract of {@code finalize} is that it is invoked if and when
* the Java™ virtual machine has determined that there is no longer any
* means [by which this object can be accessed] by any thread that has not yet
* died, except as a result of an action taken by [the finalization of](最终确定)
* some other object or class which is ready to be finalized(已完成). The
* {@code finalize} method may take any action, including making this object
* available again to other threads; the usual purpose of {@code finalize},
* however, is to perform cleanup actions before the object is
* [irrevocably](不可撤销地) discarded. For example, the finalize method for an
* object that represents an input/output connection might perform explicit(显式)
* I/O transactions(事务) to break the connection before the object is permanently
* discarded.
* <p>
* The {@code finalize} method of class {@code Object} performs no special
* action; it simply returns normally. Subclasses of {@code Object} may override
* this definition.
* <p>
* The Java programming language does not guarantee which thread will invoke the
* {@code finalize} method for any given object. It is guaranteed, however, that
* the thread that invokes finalize will not be holding any user-visible
* synchronization locks when finalize is invoked. If an uncaught exception is
* thrown by the finalize method, the exception is ignored and finalization of
* that object terminates. [如果finalize()方法引发了未捕获的异常,则该异常会被忽略,并终止该对象的清除]
* [调用finalize()方法的线程不会持有任何用户可见的同步锁]
* <p>
* After the {@code finalize} method has been invoked for an object, no further
* action is taken until the Java virtual machine has again determined that
* there is no longer any means by which this object can be accessed by any
* thread that has not yet died, including possible actions by other objects or
* classes which are ready to be finalized, at which point the object may be
* discarded. [当对象调用了finalize()方法后,JVM不会立即清除该对象,而是等到JVM第二次确认该对象没有被应用的时候,才进行GC操作]
* [finalize()方法给对象一次救活的机会]
* <p>
* The {@code finalize} method is never invoked more than once by a Java virtual
* machine for any given object. [任何对象只能调用一次finalize()方法]
* <p>
* Any exception thrown by the {@code finalize} method causes the finalization
* of this object to be halted(停止), but is otherwise ignored[但该异常被忽略].
*
* @throws Throwable
* the {@code Exception} raised by this method
* @see java.lang.ref.WeakReference
* @see java.lang.ref.PhantomReference
* @jls 12.6 Finalization of Class Instances
*/
protected void finalize() throws Throwable {
}
可得出如下结论:
a) finalize()
方法被垃圾收集器用于清除不再被引用的对象;
b) 一个子类重写了finalize()
方法用于处理系统资源或执行其他清除操作;
c) 当一个对象被确定不可再引用的时候,finalize()
方法执行清除操作;finalize()
不一定被jvm调用,只有当垃圾回收器要清除垃圾时才被调用;
d) 代表输入/输出连接的对象的finalize()
方法可能会执行显式I/O事务,以在永久丢弃该对象之前中断连接。
e) 如果finalize()
方法引发了未捕获的异常,则该异常会被忽略,并终止该对象的清除;调用finalize()
方法的线程不会持有任何用户可见的同步锁;
g) 当对象调用了finalize()
方法后,JVM不会立即清除该对象,而是等到JVM第二次确认该对象没有被应用的时候,才进行GC操作;
h) finalize()
方法给对象一次救活的机会;任何对象只能调用一次finalize()
方法;