JDK源码lang包分析——Object源码(1)

Object源码分析

Object的概述

Object类是Java中所有类的基类,在编译时会自动导入,位于java.lang包中,而Object中具有的属性和行为,是Java语言设计背后的思维体现。

Object的方法

Object类中的大部分方法都是native方法,用此关键字修饰的方法是Java中的本地方法,一般是用C/C++语言来实现。

registerNatives方法

//其主要作用是将C/C++中的方法映射到Java中的native方法,实现方法命名的解耦。函数的执行是在静态代码块中执行的,在类首次进行加载的时候执行。
private static native void registerNatives();
    static {
        registerNatives();
    }

getClass方法

//getClass就是获得类的意思,由注释可以知道,这个方法主要是获得该类的完整名称。
public final native Class<?> getClass();

hashCode方法

/*
哈希码的通用约定如下:
1.在java程序执行过程中,在一个对象没有被改变的前提下,无论这个对象被调用多少次,hashCode方法都会返回相同的整数值。对象的哈希码没有必要在不同的程序中保持相同的值。
2.如果2个对象使用equals方法进行比较并且相同的话,那么这2个对象的hashCode方法的值也必须相等。
3.如果根据equals方法,得到两个对象不相等,那么这2个对象的hashCode值不需要必须不相同。但是,不相等的对象的hashCode值不同的话可以提高哈希表的性能。
在实际使用中,要尽量保证对于不同的对象产生不同的哈希码。hashCode的典型实现是将对象的内部地址转为一个整数,但是这种实现技术不是Java语言必须要采用的。
*/
public native int hashCode();

equals方法

/*
Object中的equals方法是直接判断this和obj本身的值是否相等,即用来判断调用equals的对象和形参obj所引用的对象是否是同一对象,所谓同一对象就是指内存中同一块存储单元,如果this和obj指向的是同一块内存对象,则返回true,如果this和obj指向的不是同一块内存,则返回false,注意:即便是内容完全相等的两块不同的内存对象,也返回false。
*/
 public boolean equals(Object obj) {
        return (this == obj);
    }

clone方法

(1)此类实现了Cloneable接口,以指示Object的clone()方法可以合法地对该类实例进行按字段复制;
(2)如果在没有实现Cloneable接口的实例上调用Object的clone()方法,则会导致抛出CloneNotSupporteddException;
(3)按照惯例,实现此接口的类应该使用公共方法重写Object的clone()方法,Object的clone()方法是一个受保护的方法;
因此想实现clone的话,除了继承Object类外,还需要实现Cloneable接口;
创建并返回此对象的一个副本。对于任何对象x,表达式:
(1)x.clone() != x为true
(2)x.clone().getClass() == x.getClass()为true
(3)x.clone().equals(x)一般情况下为true,但这并不是必须要满足的要求

protected native Object clone() throws CloneNotSupportedException;
//Cloneable接口
public interface Cloneable {//空的接口
}
浅克隆( shallow clone)和 深克隆( deep clone)

浅克隆:Object的clone提供的就是浅克隆,只克隆了自身对象和对象内实例变量的地址引用,它内部的实例变量还是指向原先的堆内存区域。

深克隆:克隆所有的对象,包括自身以及自身内部对象。方法有两种:
1.先对对象进行序列化操作,然后立马反序列化出。

2.先调用super.clone()方法克隆出一个新对象来,然后在子类的clone()方法中手动给克隆出来的非基本数据类型(引用类型)赋值。

notify方法

通知可能等待该对象的对象锁的其他线程。由JVM(与优先级无关)随机挑选一个处于wait状态的线程。

  • 在调用notify()之前,线程必须获得该对象的对象级别锁
  • 执行完notify()方法后,不会马上释放锁,要直到退出synchronized代码块,当前线程才会释放锁
  • notify()一次只随机通知一个线程进行唤醒
 public final native void notify();

notifyAll方法

和notify()差不多,只不过是使所有正在等待池中等待同一共享资源的全部线程从等待状态退出,进入可运行状态
让它们竞争对象的锁,只有获得锁的线程才能进入就绪状态
每个锁对象有两个队列:就绪队列和阻塞队列

  • 就绪队列:存储将要获得锁的线程
  • 阻塞队列:存储被阻塞的线程
public final native void notifyAll();

wait方法

//Objetc中的三种wait方法
//线程等待方法,timeout表示要等待的最长时间(以毫秒为单位),调用该方法后,线程会放弃对象锁,进入等待此对象的等待锁定池
public final native void wait(long timeout) throws InterruptedException;
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);
    }
public final void wait() throws InterruptedException {
        wait(0);
    }

可见wait()和wait(long timeout, int nanos)都在在内部调用了wait(long timeout)方法。
下面主要是说说wait(long timeout)方法
wait方法会引起当前线程阻塞,直到另外一个线程在对应的对象上调用notify或者notifyAll()方法,或者达到了方法参数中指定的时间。
调用wait方法的当前线程一定要拥有对象的监视器锁。
wait方法会把当前线程T放置在对应的object上的等到队列中,在这个对象上的所有同步请求都不会得到响应。线程调度将不会调用线程T,在以下四件事发生之前,线程T一直处于休眠状态(线程T是在其代码中调用wait方法的那个线程)

当其他的线程在对应的对象上调用notify方法,而在此对象的对应的等待队列中将会任意选择一个线程进行唤醒。
其他的线程在此对象上调用了notifyAll方法
其他的线程调用了interrupt方法来中断线程T
等待的时间已经超过了wait中指定的时间。如果参数timeout的值为0,不是指真实的等待时间是0,而是线程等待直到被另外一个线程唤醒。
被唤醒的线程T会被从对象的等待队列中移除并且重新能够被线程调度器调度。之后,线程T会像平常一样跟其他的线程竞争获取对象上的锁;一旦线程T获得了此对象上的锁,那么在此对象上的所有同步请求都会恢复到之前的状态,也就是恢复到wait被调用的情况下。然后线程T从wait方法的调用中返回。因此,当从wait方法返回时,对象的状态以及线程T的状态跟wait方法被调用的时候一样。
线程在没有被唤醒,中断或者时间耗尽的情况下仍然能够被唤醒,这叫做伪唤醒。虽然在实际中,这种情况很少发生,但是程序一定要测试这个能够唤醒线程的条件,并且在条件不满足时,线程继续等待。

等待/唤醒机制的常见用法

Java多线程开发中,我们常用到wait()和notify()方法来实现线程间的协作,简单的说步骤如下:
1.A线程取得锁,执行wait(),释放锁;
2.B线程取得锁,完成业务后执行notify(),再释放锁;
3.B线程释放锁之后,A线程取得锁,继续执行wait()之后的代码;(请参考下面的代码一,线程相互通信)
详情可以看这篇博客:https://blog.csdn.net/chase_ACM/article/details/88936827

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值