Object 方法介绍
Object类当中包含的⽅法有12个:
1.需要重写 toString(),equals(),hashCode();
2.线程有关:wait方法, notify(), notifyAll();
3.其他 getClass(),finalize(), clone(),registerNatives;
2.线程有关:wait方法, notify(), notifyAll();
3.其他 getClass(),finalize(), clone(),registerNatives;
1 toString:返回该对象的字符串表示,其实该字符串内容就是对象的类型+@+内存地址值. 如果不希望使用默认的方法,需要重写toString方法。
2 hashCode:native方法,用于返回对象的hash码,主要是用在哈希表中,如jdk的HashMap
3 equals:指示其它对象是否与此对象是否相等。一般有默认与自定义两种方式。默认地址比较法,'==' 进行对象地址的比较,如果不是同一个对象,则必然返回false; 另一种是对象内容比较,则需要重写queals方法。在比较两个对象的时候,容易抛空指针异常。
4 getClass: 返回此Object的运行时类。Java的引用变量有两种类型,编译时类型和运行时类型。编译时类型是有声明该变量时使用的类型决定(=左边)。运行时类型由实际赋值给变量的对象决定(= 右边)
5 clone: 复制对象。复制有两种方式,深克隆:复制一份全新的,属性内一致,但是内存中的地址值不一样的对象。浅克隆:复制引用。
6 finalize: Gc垃圾回收机制。
7 wait(long): native方法,不能重写,其作用是暂停线程的运行,释放锁。timeout 是等待时间。
8 wait(long,int): 相比于wait(long),多了nanos参数,表示额外的时间(以毫秒为单位,范围是 0 - 999999)
9 notify: native方法,不能被重写,唤醒一个在此对象监视器上等待的线程,监视器也就是锁。有多个等待的线程时,则随机唤醒一个。
10 notifyAll: native方法,不能被重写。唤醒在此对象监视器上等待的所有线程。
12 registerNatives: 静态方法,创建Java对象时,系统总是先调用静态初始化块,当系统调用该方法时,注册此类中的native方法。
wait与notify方法测试样例:
/*
在调用wait方法时,线程必须持有被调用对象的锁,当调用wait方法后,该线程就会释放掉该对象的锁(monitor)
在调用thread的sleep方法时,线程不会释放掉线程对象的锁
关于wait、notify和notifyAll方法的总结:
1.当调用wait方法时,首先需要确保调用了wait方法的线程已经持有了对象的锁
2.当调用wait后,该线程就会释放掉该对象的锁,然后进入到等待状态
3.当线程调用wait后进入到等待状态时,它就可以等待其他线程调用相同对象的notify或者notifyAll方法使得自己被唤醒
4.一旦这个线程被其它线程唤醒后,该线程就会与其他线程一同开始竞争这个对象的锁(公平竞争);
只有当线程重新获取到该对象的锁后,线程才会继续往下执行。
5. 调用wait方法的代码片段必须放到synchronized块或者synchronized方法中,这样才可以确保线程在调用wait
方法前已经获取到了对象的锁
6.当调用对象的notify方法时,它就会随机该对象等待集合中的任意一个线程,当某线程被唤醒后,它就会与其它线程一同竞争
对象的锁
7.当调用对象的notifyAll方法时,它就会该对象等待集合中的所有线程,这些线又会开始竞争对象的锁
8.在某一个时刻,只有一个线程可以拥有对象的锁
*/
public class MyObject {
public static void main(String[] args) throws InterruptedException { Object obj = new Object(); //先要获取对象的锁 synchronized (obj){ obj.wait(); } } public class MyTest{
//先获取MyTest对象实例的锁,如果是同一个实例,则该实例的其它的被synchronized修饰的方法暂时得不到执行 public synchronized void method1(){ System.out.println("execute method1"); System.out.println("method1 begin await"); try { wait(); } catch (InterruptedException e) { e.printStackTrace(); }
//执行完wait方法后就释放锁,其它被synchronized修饰的方法可以开始执行,同时该方法进入该对象的等待队列中,直到被通知后,才继续往下执行。
System.out.println("method1 continue"); //通知其它在等待的方法,如method2 notify(); System.out.println("notify method2 continue"); } public synchronized void method2(){ System.out.println("execute method2");
//通知其它在等待的方法,如method1
notify(); System.out.println("notify method1 continue"); System.out.println("method2 begin await");
//method2进入等待队列,并释放锁。 try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("method2 continue"); } } @Test public void testSameInstanceCallMethod(){ MyTest myTest = new MyTest(); Thread thread1 = new Thread(()->{ myTest.method1(); }); Thread thread2 = new Thread(()->{ myTest.method2(); }); thread1.start(); sleep(1000); thread2.start(); } }
测试结果:
execute method1 method1 begin await execute method2 notify method1 continue method2 begin await method1 continue notify method2 continue method2 continue
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix