Object根父类
方法五:object clone()
protected native Object clone() throws CloneNotSupportedException;
作用:创建并返回此对象的副本
tips:
1、保证克隆对象将有单独的内存地址分配,即相对原始对象独立存在。
2、原始和克隆的对象应该具有相同的类类型,但并不是强制的。
3、原始和克隆的对象应该是平等的equals()方式使用,但也不是强制的。
4、每个类直接或间接的父类都是Object,所以他们都包含clone方法,但是此方法使用protected修饰的,所以不能再类外访问。如果需要对一个对象进行赋值,就需要对clone方法覆盖
Q:为什么要克隆?
经过clone()方法克隆的对象可能包含一些已经修改过的属性,而新new出来的对象的属性还是初始化时候的值。所以当需要一个新的对象来保存当前对象的状态就是用clone方法。因为clone使用native修饰的,因此它是可以在底层实现的,速度很快!
Besides
Object obj1 = new Objecet();
Object obj2;
obj2 = obj1;
这种形式的代码复制是引用,即对象在内存中的地址,两个对象仍然指向的同一个对象。一损俱损一荣俱荣!
Object obj1 = new Object();
obj1.setName("a");
Object obj2 = (Object)obj1.clone();
clone方法复制的对象和原来的对象是同时独立存在的,互不影响!
So——>
Q:How to achieve the method clone?
在Java语言中,数据类型分为值类型和引用类型。
值类型:int、double、byte、boolean、char等简单数据类型。
引用类型:类、数组、接口等复杂类型。
浅克隆和深克隆的主要区别在于是否支持引用类型成员变量的赋值:
1、被赋值的类需要实现Cloneable接口(如果没有实现会抛出异常)
2、覆盖clone()方法,访问修饰符设置为public。方法中调用super.clone()方法得到需要的复制对象(native为本地底层方法)
在网上找了一个例子:
class Address implements Cloneable {
private String add;
public String getAdd() {
return add;
}
public void setAdd(String add) {
this.add = add;
}
//覆盖clone方法
@Override
public Object clone() {
Address addr = null;
try{
addr = (Address)super.clone();
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
return addr;
}
}
class Student implements Cloneable{ //实现Clonealbe接口
private int number;
private Address addr;
public Address getAddr() { 3
return addr;
}
public void setAddr(Address addr) {
this.addr = addr;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
@Override
public Object clone() {
Student stu = null;
try{
stu = (Student)super.clone(); //浅复制
}catch(CloneNotSupportedException e) {
e.printStackTrace();
}
stu.addr = (Address)addr.clone(); //深度复制
return stu;
}
}
public class Test {
public static void main(String args[]) {
Address addr = new Address();
addr.setAdd("杭州市");
Student stu1 = new Student();
stu1.setNumber(123);
stu1.setAddr(addr);
Student stu2 = (Student)stu1.clone();
System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
addr.setAdd("西湖区");
System.out.println("学生1:" + stu1.getNumber() + ",地址:" + stu1.getAddr().getAdd());
System.out.println("学生2:" + stu2.getNumber() + ",地址:" + stu2.getAddr().getAdd());
}
}
结果:
学生1:123,地址:杭州市
学生2:123,地址:杭州市
学生1:123,地址:西湖区
学生2:123,地址:杭州市
- 在浅克隆中,当对象被复制时只复制它本身和其中包含的值类型的成员变量,而引用类型的成员对象并没有复制。
- 在深克隆中,除了对象本身被复制外,对象所包含的所有成员变量也将复制。
方法六:String toString()
public String toString() {
return getClass().getName() + "@"
+ Integer.toHexString(hashCode());
}
作用:返回对象的字符串表示形式,建议所有子类都覆盖toString方法。方便所有类的字符串操作。
返回值:对象的字符串(文本形式),类名+@+此对象哈希吗的无符号十六进制表示
例如,System.out.println(xx)括号里的“xx”如果不是String类型,就会自动调用toString方法。
Tip:
1、undefined和null没有toString()方法
也就是说,码代码的时候你不可以这样写!
undefined.toString();//error
null.toString();//error
2、boolean类型的返回对应的true和false
true.toString();//true
false.toString();//false
3、字符串类型就按原值返回
'1'.toString();//'1'
'aaa'.toString();//‘aaa’
4、数值类型的情况
Number.toString();//"function Number(){native code})"
①正浮点数以及NaN、Infinity
(NaN是Not A Number的缩写,用于处理计算中出现的错误情况。Infinity是指无穷大)
0.55.toSting();//'0.55'
NaN.toString();//'Nan'
Infinity.toString();//'Infinity'
②、负浮点数或带“+”的正浮点数。相当于先运行tostring()方法,再添加正负号,转换为数字
+0.55.toString();//0.55
typeof+0.55.toString();//'number'
-0.55.toString();//-0.55
typeof -0.55.toString();//'number'
③、整数直接+toString()形式会报错,提示无效标记,因为整数后的点会被识别为小数点.所以为了避免这个问题需要加括号
0.toString();//Uncaught SyntaxError:Invalid or unexpected token
(0).toString();//'0'
(-0).toString();//'0'
(+0.5).toString();//'0.5'
(-0.5).toString();//'-0.5'
(NaN).toString();//'NaN'
④数据类型的toString方法可以接受表示转换基数(radix)的可选参数,如果不指定参数,转换轨则默认为十进制,同样也可以加参数转换为其他进制数
var a = 17;
n.toString();//'17'
n.toString(2);//'10001'
⑤对象Object类型及自定义对象类型加括号返回
function Person(){
this.name = 'test';
}
var per = new Person();
per.toString();//"[Object Object]"
返回到最初的println的例子:
public class Main {
public static void main(String[] args) {
String a=new String();
a="hello world";
System.out.println(a);//相当于
System.out.println(a.toString());
}
}
方法七-十一:notify系列和wait系列
储备:
所有对象都有一个与之关联的锁与监视器。
what?什么是锁?什么是监视器?
锁:逻辑上锁是对象内存堆中头部的一部分数据。JVM中每个对象都有一个锁(互斥锁),任何程序都可以使用它来协调对对象的多线程访问。如果任何线程想要访问该对象的实例变量,那么线程必须拥有该对象的锁(通过在锁内存区域设置一些标志)。所有其他的线程视图访问该对象的变量必须等到拥有该对象的锁的线程释放锁(改变标记)
一旦线程拥有一个锁,他可以多次请求相同的锁,但是在其他线程能够使用这个对象之前必须释放相同次数的锁。
1)锁可以用来保护代码段,任何时刻只能有一个线程执行被保护的代码
2)锁可以管理视图进入被保护代码的线程
3)锁以拥有一个或多个相关的条件对象
从1.0版本开始,Java中的每一个对象都有一个内部锁。如果一个方法用synchronized关键字声明,那么对象的锁将保护整个方法。也就说,要调用该方法,线程必须获得内部的对象锁。
我的一些理解:
这里可以联想到操作系统的PV操作互斥访问临界资源的相关知识,有几次P操作,就需要几次V操作来释放临界资源。这里大概是相似的意思,均是互斥访问临界资源。
监视器:是一种同步结构,它允许线程同时互斥(使用锁)和协作,即赋予使用等待集(wait-set)使线程等待某些条件为真的能力。
监视器就像一个包含一个特殊房间的家住无,这个特殊房间就是对象实例,每次只能占用一个线程。通常,这个房间包含一些需要放置并发访问的数据。从一个线程进入这个房间到它离开的时间,它可以独占访问房间中的任何数据。
进入监控的建筑被称为“进图监控监视器”
进入建筑颞部特殊房间叫做“获取监视器”
房间占领被称为“拥有监视器”
离开房间被称为“释放监视器”
退出整个建筑被称为“退出监视器”
访问和退出的全过程:
当一个线程访问受保护的数据(进入特殊的房间)时,它首先在建筑物接收(entry-set)中排队。如果没有其他线程在等待(拥有监视器),线程获取锁并继续执行受保护的代码。当线程完成执行时,它释放锁并退出大楼(退出监视器)。
如果当一个线程到达并且另一个线程已经拥有监视器时,它必须在接收队列中等待(entry-set)。当当前所有者退出监视器时,新到达的线程必须与在入口集中等待的其他线程竞争。只有一个线程能赢得竞争并拥有锁。
Java中的每个对象有一个内部的锁和内部条件。如果一个方法用synchronized关键字声明,那么,它表现的就像一个监视器方法。通过wait/notifyAll/nofify来访问条件变量
1、wait():
使当前线程阻塞,处于等待状态(Wait),并将当前线程置入锁对象的等待对了,直到被通知(notify)或被中断。
前提是必须先获得锁,一般配合synchronized关键字使用。即,一般在synchronized同步代码块里使用wait()、notify()/notifyAll()方法
2、notify():
唤醒处于等待状态的线程。在同步方法或同步代码快汇总使用,如果对个线程在等待,随机挑选一个线程唤醒(由jdk版本决定)。notify方法调用后,当前线程不会立即释放对象锁,要等到当前线程执行完毕后再释放。也就是说,notify/notifyAll() 的执行只是唤醒沉睡的线程,而不会立即释放锁,锁的释放要看代码块的具体执行情况。所以在编程中,尽量在使用了notify/notifyAll() 后立即退出临界区,以唤醒其他线程让其获得锁
3、notifyAll():
唤醒所有处于等待状态的线程
notify方法只唤醒一个等待(对象的)线程并使其开始执行。所以如果有多个线程在等待同一个对象,这个方法只会唤醒其中一个,选择哪个线程取决于操作系统对多线程管理的实现。
notifyAll会唤醒所有等待(对象的)线程,尽管哪一个线程将会第一个处理取决于操作系统的实现。如果当前情况下有多个线程需要被唤醒,推荐使用notifyAll 方法。比如在生产者-消费者里面的使用,每次都需要唤醒所有的消费者或是生产者,以判断程序是否可以继续往下执行。
notify唤醒沉睡的线程后,线程会接着上次的执行继续往下执行。所以在进行条件判断时候,可以先把 wait 语句忽略不计来进行考虑;显然,要确保程序一定要执行,并且要保证程序直到满足一定的条件再执行,要使用while进行等待,直到满足条件才继续往下执行。
public class K {
//状态锁
private Object lock;
//条件变量
private int now,need;
public void produce(int num){
//同步
synchronized (lock){
//当前有的不满足需要,进行等待,直到满足条件
while(now < need){
try {
//等待阻塞
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("我被唤醒了!");
}
// 做其他的事情
}
}
}
由于上面三种方法都是在同步代码快里执行,所以当前线程一定是已经获取了锁的
当线程执行wait()方法时,会释放当前锁,让出CPU(或其他临界资源),进入wait状态
只有当notify或notifyAll执行时,才会唤醒一个或多个等待状态的线程,然后继续执行。直到执行完同步代码快的代码或者中途遇到wait,再次释放锁,是一个类似递归的过程。
方法十二: void finalize()
protected void finalize() throws Throwable { }
作用:回收特殊渠道申请的内存。Java程序有垃圾回收器,所以一般情况下内存问题不用程序员操心。但有一种JNI(Java Native Interface)调用non-Java程序(C或C++),finalize()的工作就是回收这部分的内存。
即当某个对象变成一个垃圾对象,内存被回收时就会调用系统中定义的finalize方法来完成。
不建议用finalize方法完成“非内存资源”的清理,因为Java的自动垃圾回收器不会失去平衡,作为便利的代价,不得不放弃对系统资源释放的控制,Java Applet不会自动执行类中的finalize()方法,即使使用1.0版本试图强制调用也不能确保将它调用。
因此不建议依靠finalize来执行你的Applet和应用程序的资源清理工作。取而代之,我们应当明确得清除那些资源或使用类似try…finally块的机制来实现。
相关源码详细注释:
/**
* 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:
*
* 创建并返回此对象的副本。
* “复制”的确切含义可能取决于对象的类别。
* 一般意义是,对于任何对象 x表达式:
*
* x.clone() != x
* will be true, and that the expression:
* x.clone().getClass() == x.getClass()
* will be {@code true}, but these are not absolute requirements.
* While it is typically the case that:
* x.clone().equals(x)
* will be {@code true}, this is not an absolute requirement.
*
* x.clone() != x 为真,,并且表达式:
* x.clone().getClass() == x.getClass()为真,但这些不是绝对要求。
* 通常的情况是:
* x.clone().equals(x) 为真,这不是绝对要求。
*
* 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()}.
*
* 按照约定,返回的对象应该通过调用获得super.clone。
* 如果一个类和它的所有超类(Object 除外)都遵守这个约定,
* 那么 x.clone().getClass() == x.getClass() 就是这种情况。
*
* 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.
*
* 按照惯例,这个方法返回的对象应该独立于这个对象(它被克隆)。
* 为了实现这种独立性,可能需要在返回之前修改 super.clone返回的对象的一个或多个字段。
* 通常,这意味着复制包含被克隆对象的内部“深层结构”的任何可变对象,并将对这些对象的引用替换为对副本的引用。
* 如果一个类只包含原始字段或对不可变对象的引用,那么通常情况下,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.
* <p>
* clone()执行特定的克隆操作。
* 首先,如果这个对象的类没有实现接口cloneable,则抛出一个异常 CloneNotSupportedException
* 请注意,所有数组都被认为实现了接口 cloneable,并且数组类型 T[] 的 clone方法的返回类型是 T[],其中 T 是 任何引用或原始类型。
* 否则,此方法会创建此对象的类的新实例,并使用此对象的相应字段的内容来初始化其所有字段,就像通过赋值一样; 字段的内容本身不会被克隆。
* 因此,此方法执行此对象的“浅拷贝”,而不是“深拷贝”操作。
* 也就是说:除开数组外,如果对象的类没有实现Cloneable接口,则拷贝后会自动创建一个类的新的实例,并对这个实例的所有字段进行初始化
*
* 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.
* 抛出:CloneNotSupportedException
* 如果对象的类不支持 Cloneable 接口。 覆盖clone方法的子类也可以抛出此异常以指示无法克隆实例。
* @see java.lang.Cloneable
*/
protected native Object clone() throws CloneNotSupportedException;
/**
* 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>
* 返回对象的字符串表示形式,通常情况下,toString方法返回一个字符串以文本的形式表示这个对象
* 返回结果应该是一个简洁但信息丰富的表示并且易于阅读
* 建议所有子类都覆盖toString方法
*
*
* 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:
* getClass().getName() + '@' + Integer.toHexString(hashCode())
*
* Object类的 toString方法返回一个字符串,该字符串由对象是其实例的类的名称、
* at-sign 字符 `{@code @}' 和对象hash值的无富含十六进制表示组成。
* 换句话说,此方法返回一个等于以下值的字符串:
* getClass().getName() + '@' + Integer.toHexString(hashCode())
*
* @return a string representation of the object.
* 返回值:对象的字符串表示
*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
/**
* 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.
*
* 唤醒在此对象的监视器上等待的单个线程。
* 如果有任何线程正在等待该对象,则选择其中一个线程被唤醒。
* 选择是任意的,并且由实现决定。
* 线程通过调用 wait方法之一在对象的监视器上等待。
*
* <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.。,1
*通过执行该对象的同步实例方法。
*通过执行在对象上同步的synchronized语句的主体。
*对于 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();//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.
* 唤醒在此对象监视器上等待的所有线程。
* 线程通过调用wait方法之一在对象的监视器上等待。
*
* <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.
* 此方法只能由作为此对象监视器的所有者的线程调用。
* 有关线程可以成为监视器所有者的方式的描述,请参阅notify方法。
*
* @throws IllegalMonitorStateException if the current thread is not
* the owner of this object's monitor.
* 与notify相同
* @see java.lang.Object#notify()
* @see java.lang.Object#wait()
*/
public final native void notifyAll();
/**
* 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.
* 使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()}方法,
* 或指定等待时间已经过去了。
*
*
* The current thread must own this object's monitor.
* 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:
* 当前线程必须拥有此对象的监视器。
* 此方法使当前线程(称为 <var>T</var>)将自己置于此对象的等待集中,然后放弃对该对象的任何和所有同步声明。
* 线程 T出于线程调度目的而被禁用并处于休眠状态,直到发生以下四种情况之一:
*
* Some other thread invokes the {@code notify} method for this
* object and thread T happens to be arbitrarily chosen as
* the thread to be awakened.
* Some other thread invokes the {@code notifyAll} method for this
* object.
*Some other thread {@linkplain Thread#interrupt() interrupts}
* thread T.
* 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.
*某个其他线程为此对象调用 notify方法,并且线程 T恰好被任意选择为要唤醒的线程。
*其他一些线程为此对象调用notifyAll方法。
*其他一些线程 interrupt()线程T。
*或多或少已经过了指定的实时时间。 但是,如果timeout为零,则不考虑实时性,线程只是等待直到收到通知。
*
*
* 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.
*然后,线程 T 从该对象的等待集中移除,并重新启用线程调度。
*然后它以通常的方式与其他线程竞争在对象上同步的权利;
* 一旦它获得了对象的控制权,它对对象的所有同步声明都将恢复到状态 - 即调用 wait 方法时的情况。
* 然后线程 T 从 wait 方法的调用中返回。
* 因此,从 wait 方法返回时,对象和线程 T 的同步状态与调用 wait 方法时完全相同。
*
*
* <p>
* A thread can also wake up without being notified, interrupted, or
* timing out, a so-called <i>spurious 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).
* (有关此主题的更多信息,请参阅 Doug Lea 的“Java 中的并发编程(第二版)”(Addison-Wesley,2000)中的第 3.2.3 节,
* 或 Joshua Bloch 的“Effective Java Programming Language Guide”(Addison- 韦斯利,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.
* 如果当前线程在等待之前或等待时被任何线程中断,则抛出 InterruptedException。
* 直到如上所述恢复此对象的锁定状态后,才会抛出此异常。
*
* <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.
* 请注意,wait 方法将当前线程放入此对象的等待集中,因此仅解锁此对象;
* 当前线程可能同步的任何其他对象在线程等待时保持锁定。
* <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.
* 此方法只能由作为此对象监视器的所有者的线程调用。
* 有关线程可以成为监视器所有者的方式的描述,请参阅notify方法。
*
* @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.
* 使当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法,
* 或其他一些线程中断 当前线程;或者已经过去了一定的实时时间。
* <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:
* 此方法类似于一个参数的 wait 方法,但它允许更好地控制在放弃之前等待通知的时间量。
* 以纳秒为单位测量的实时量由下式给出:
* 1000000*timeout+nanos
*
* In all other respects, this method does the same thing as the
* method wait(long) of one argument. In particular,
* {@code wait(0, 0)} means the same thing as {@code wait(0)}.
* 在所有其他方面,此方法与一个参数的方法 wait(long) 执行相同的操作。
* 特别是,wait(0, 0)}与wait(0)的含义相同。
*
* <p>
* The current thread must own this object's monitor. The thread
* releases ownership of this monitor and waits until either of the
* following two conditions has occurred:
*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 timeout period, specified by {@code timeout}
* milliseconds plus {@code nanos} nanoseconds arguments, has elapsed.
* 当前线程必须拥有此对象的监视器。 线程释放此监视器的所有权并等待,直到发生以下两种情况之一:
* 另一个线程通过调用 notify 方法或notifyAll方法通知等待此对象监视器的线程唤醒。
* 由 timeout毫秒加上nanos 纳秒参数指定的超时时间已经过去。
*
*
* The thread then waits until it can re-obtain ownership of the
* monitor and resumes execution.
*然后线程等待直到它可以重新获得监视器的所有权并恢复执行。
*
* 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.
* 此方法只能由作为此对象监视器的所有者的线程调用。
* 有关线程可以成为监视器所有者的方式的描述,请参阅 notify方法。
*
*
* @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 {
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 > 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)}.
* 使当前线程等待,直到另一个线程为此对象调用 notify() 方法或 notifyAll()方法。
* 换句话说,这个方法的行为就像它只是执行调用 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.
* 当前线程必须拥有此对象的监视器。
* 线程释放此监视器的所有权并等待,直到另一个线程通过调用 notify 方法或 notifyAll方法通知在此对象监视器上等待的线程唤醒。
* 然后线程等待直到它可以重新获得监视器的所有权并恢复执行。
*
* <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.
* 此方法只能由作为此对象监视器的所有者的线程调用。
* 有关线程可以成为监视器所有者的方式的描述,请参阅 notify方法。
*
* @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);
}
/**
* Called by the garbage collector on an object when garbage collection
* 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.
* 当垃圾收集器确定不再有对对象的引用时,由垃圾收集器在对象上调用。
* 子类覆盖finalize方法来处理系统资源或执行其他清理。
*
* <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.
* finalize 的一般约定是它在 Java&trade时被调用。
* 虚拟机已确定不再有任何方法可以让任何尚未终止的线程访问此对象,除非由于某些其他对象或类已准备好终止而采取的行动 .
* finalize方法可以执行任何操作,包括使该对象再次可供其他线程使用;
* 然而,finalize 的通常目的是在对象被不可撤销地丢弃之前执行清理操作。
* 例如,表示输入/输出连接的对象的 finalize 方法可能会执行显式 I/O 事务以在对象被永久丢弃之前中断连接。
*
* <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.
* Object 类的 finalize 方法不执行任何特殊操作; 它只是正常返回。 Object 的子类可以覆盖这个定义。
*
* <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.
* Java 编程语言不保证哪个线程将调用任何给定对象的 finalize 方法。
* 但是,可以保证调用 finalize 的线程在调用 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方法后,不会采取进一步的操作,
* 直到 Java 虚拟机再次确定任何尚未终止的线程都无法再访问该对象 ,
* 包括准备好完成的其他对象或类的可能操作,此时该对象可能会被丢弃。
*
* <p>
* The {@code finalize} method is never invoked more than once by a Java
* virtual machine for any given object.
* 对于任何给定对象,Java 虚拟机永远不会多次调用 finalize 方法。
*
* <p>
* Any exception thrown by the {@code finalize} method causes
* the finalization of this object to be halted, but is otherwise
* ignored.
* finalize 方法抛出的任何异常都会导致此对象的终结被暂停,但会被忽略。
*
* @throws Throwable the {@code Exception} raised by this method
*抛出:由此方法引发的Exception
* @see java.lang.ref.WeakReference
* @see java.lang.ref.PhantomReference
* @jls 12.6 Finalization of Class Instances
*/
protected void finalize() throws Throwable { }