JAVA源码剖析之---Object类(三)---toString,wait,notify,notifyAll,finalize方法的使用
来源:互联网 发布:学术猫数据库 编辑:程序博客网 时间:2024/05/16 09:53
今天剖析的方法有:toString()方法,notify()方法,notifyAll()方法,wait()方法,wait(args)方法,wait(args,args)方法,finalize()方法。
第6个方法:
public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
该方法为被public修饰,所有对象都可见。
该方法返回对象的字符串表示形式,开发人员能够清晰的看到一个对象的各种属性。在官方建议上,建议所有的方法都重写这个方法。Eclipse有代码生成器,可以方便的重写该方
法。
看方法体的内容,可以知道,最终返回getClass().getName() + ' @' + Integer.toHexString(hashCode())。下面用一个例子看一下:
举例:
package edu.java.test;public class TestToString {public static void main(String[] args) {TestClone tc = new TestClone();tc.setName("my name is java");tc.setAge("70 yeas");System.out.println("未重写之前的toString方法:"+tc.getClass().getName()+"@"+Integer.toHexString(tc.hashCode()));System.out.println("重写之后的toString方法:"+tc.toString());}}
上面示例了两个打印语句,一个是原生态的toString方法,一个是重写后的toString方法。下面是结果:
未重写之前的toString方法:edu.java.test.TestClone@1e57e8f重写之后的toString方法:TestClone [name=my name is java, age=70 yeas]
可以看出,原生态的toString方法,不能很好的显示出对象的属性,所以在toString源码里,java开发人员建议每个类都应该重写toString方法的原因。下面是重写后的toString方法。
@Overridepublic String toString() {return "TestClone [name=" + name + ", age=" + age + "]";}
第7个方法:wait()
public final void wait() throws InterruptedException { wait(0); }
该方法会导致当前线程等待,直到另一个线程调用notify()或者notifyAll()方法或者是设定的等待时间过去。
当前线程必须拥有此对象监视器。如果线程等待,有以下四种方式可以解除等待。
第一种方式:其他线程调用notify()方法,然后该线程刚好被唤醒。
第二种方式:其他线程中断。
第三种方式:其他线程调用notifyAll()方法。
第四种方式:超时时间为0。
一旦发生上面四件事情,就会把该线程从等待设置中删除。
第8个方法:notify()
public final native void notify();
notify本意在中文中是通知的意思。该方法由final和native修饰,表明该方法是依赖于本地,不被java实现,而且不能被子类重写。
这个方法主要是唤醒一个等待中的线程。而且,这个唤醒后的线程和其他正常活跃的线程一样。
在这里要提一下wait方法,wait方法是使当前线程等待,而notify则是唤醒,而且当前运行的线程必须具有该对象的对象监视器,监视器的获得有三种方式:
第一种方式:通过执行该对象的同步的方法。在此大致介绍一下同步,同步就相当于给一个对象上了一把锁,在一段时间内,这个对象只能被一个线程访问,其他任何线程都不能进入。比如说,我现在进入了我家,然后把门锁了,这个时候其他任何没有钥匙的人都进不来。屋里面的东西只能自己动。
synchronized(object)。
第二种方式:在同步代码块中执行。
synchronized void method(){}。
第三种方式:执行一个Class类型的同步静态方法。
而这三种方式都必须要求当前线程拥有对象的监视权。
第9个方法:notifyAll();
唤醒所有线程,可能是按照线程等待时间倒叙唤醒。
以上3个方法举例:
package edu.java.test;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Calendar;public class TestNotify01 {private Object monitor = new Object();DateFormat format = new SimpleDateFormat("yyyy-MM-dd:hh:mm:ss");private String getTime(){return format.format(Calendar.getInstance().getTime());}/** * 0.首先获得对象的监视器 * 1.打印等待前后线程的名称和等待时间 * 2.线程开启 * @param thread * @param ms */public void waitOnce(String thread, final Long ms) {Thread waitThread = new Thread() {public void run() {// 对对象上锁,获得对象的监视器,用的第二种方式,对同步代码块进行上锁synchronized (monitor) {try {System.out.println("Thread等待之前 " + Thread.currentThread().getName() + " Wait at" + getTime());monitor.wait(ms);System.out.println("Thread等待之后 " + Thread.currentThread().getName() + " Wait at" + getTime());} catch (InterruptedException e) {e.printStackTrace();}}}};waitThread.setName(thread);waitThread.start();}/** * 0.获得对象的监视器 * 1.唤醒一个线程 * 2.睡眠两次 * 3.开启线程 * @param thread * @param ms */public void awake(String thread, final Long ms) {Thread notifyThread = new Thread() {public void run() {// 对对象上锁,获得对象的监视器,用的第一种方式synchronized (monitor) {monitor.notify();System.out.println("Thread" + Thread.currentThread().getName() + " 唤醒 at " + getTime());try {Thread.sleep(ms);} catch (InterruptedException e) {e.printStackTrace();}}try {Thread.sleep(ms);} catch (InterruptedException e) {e.printStackTrace();}};};notifyThread.setName(thread);notifyThread.start();}/** * 唤醒全部线程 * @param thread */public void awakeAll(String thread) {Thread notifyThread = new Thread() {public void run() {// 对对象上锁,获得对象的监视器,用的第一种方式synchronized (monitor) {monitor.notifyAll();System.out.println("Thread" + Thread.currentThread().getName() + " 唤醒 at " + getTime());}};};notifyThread.setName(thread);notifyThread.start();}public static void main(String[] args) {/** * 0.首先建立了一个对象 * 1.然后开启三个等待中的线程 * 2.睡眠两秒后唤醒一个线程,从线程的名称中可以看出,唤醒线程的顺序可能是按照线程开启时间来的. */TestNotify01 test = new TestNotify01();test.waitOnce("1",Long.MAX_VALUE);test.waitOnce("2",Long.MAX_VALUE);test.waitOnce("3",Long.MAX_VALUE);try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}test.awake("100",2000L);//test.awakeAll("100");}}
这个测试主要是先等待,然后再唤醒,可以从结果直观的感受一下:
Thread等待之前 1 Wait at2016-07-15:12:28:19Thread等待之前 2 Wait at2016-07-15:12:28:19Thread等待之前 3 Wait at2016-07-15:12:28:19Thread100 唤醒 at 2016-07-15:12:28:21Thread等待之后 1 Wait at2016-07-15:12:28:23
先等待3个线程,然后2S后唤醒,按照顺序唤醒。接下来我们看一下如果是唤醒全部,会是什么结果:
Thread等待之前 1 Wait at2016-07-15:12:29:35Thread等待之前 2 Wait at2016-07-15:12:29:35Thread等待之前 3 Wait at2016-07-15:12:29:35Thread100 唤醒 at 2016-07-15:12:29:37Thread等待之后 3 Wait at2016-07-15:12:29:37Thread等待之后 2 Wait at2016-07-15:12:29:37Thread等待之后 1 Wait at2016-07-15:12:29:37
可以看出,唤醒是倒叙唤醒的。
第10个方法:
public final native void wait(long timeout) throws InterruptedException;
这个方法就是设置时间唤醒,一段时间过后唤醒,上面的wait()方法,其实就是这个方法里的参数设置为0,也就是理解唤醒。
第11个方法:
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 >= 500000 || (nanos != 0 && timeout == 0)) { timeout++; } wait(timeout); }
这个方法和wait()方法很类似,不过它能够更精确的控制时间,并且抛出对应的异常。
如果超时时间<0,就会抛出超时时间为负的异常,因为时间必须>=0。
如果时间最小单位超过999999,就会抛出纳秒时间超出范围异常。
第12个方法:
protected void finalize() throws Throwable { }Java 技术允许使用 finalize() 方法在垃圾收集器将对象从内存中清除出去之前做必要的清理工作。
- JAVA源码剖析之---Object类(三)---toString,wait,notify,notifyAll,finalize方法的使用
- Java Object类 hashcode、 equals 、 toString、notify()、notifyAll()、finalize()
- Object类wait,notify,notifyAll的使用
- Java中的synchronized、Object.wait()、Object.notify()/notifyAll()的使用
- 【Java基础之Object类(一)】Java中Object类中的所有方法(toString、equals、hashCode、clone、finalize、wait和notify等)详解
- Object的wait、notify、notifyall方法解析
- wait()、notify()和notifyAll()Object类 的方法
- java Object 类中 notify() ,notifyAll() ,wait()
- (三)java多线程之wait notify notifyAll
- Object的notify,wait,notifyAll
- java notify()和notifyall()的区别&wait()方法的使用
- Java的notify,wait,notifyAll方法使用介绍
- 【Java基础之Object类(二)、线程同步(一)】Java中使用Object类的wait,notify,notifyAll做线程调度
- java Object 对象的的wait()、notify()、notifyAll()介绍
- wait()、notify()和notifyAll()是 Object类 中的方法
- wait()、notify()和notifyAll()是 Object类 中的方法
- 多线程开发之Object.wait() notify() notifyall()
- wait, notify, notifyAll的使用
- 在 unity 中使用三种简单的方式实现实时时钟动画
- Cocos2d-x 图像渲染和动画——裁剪(ClippingNode)
- send pkt
- python usefull lib
- topk--堆排序--小顶堆
- JAVA源码剖析之---Object类(三)---toString,wait,notify,notifyAll,finalize方法的使用
- Fragment加入到Activity的两种方式
- 重构全局系统架构的方法与工具
- Go语言学习笔记10
- UIView——layout
- 编写一个makefile的简单实例
- Cocos2d-x 3.0数据结构——cocos2d::Vector
- Activity给Fragment传参
- 佳肴 (Standard IO)