前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java基础类源码分析:Object

Java基础类源码分析:Object

原创
作者头像
冰寒火
修改2023-02-23 21:40:06
7170
修改2023-02-23 21:40:06
举报
文章被收录于专栏:软件设计软件设计

1 大纲

java.lang.Object是所有类的父类,默认继承,而且java.lang包下的所有类都由编译器自动导入,不需要显示import,因为用的多,提前加载可以提高运行时速度。

image.png
image.png

2 equals方法

"=="与equals的区别要看equals是如何重写的,在Object中两者意义等同,都是判断引用地址是否相同。在String中equals比较的是内容。

代码语言:java
复制
//Object
public boolean equals(Object obj) {
    return (this == obj);
}

//String
public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    return (anObject instanceof String aString)
            && (!COMPACT_STRINGS || this.coder == aString.coder)
            && StringLatin1.equals(value, aString.value);
}
public static boolean equals(byte[] value, byte[] other) {
    if (value.length == other.length) {
        for (int i = 0; i < value.length; i++) {
            if (value[i] != other[i]) {
                return false;
            }
        }
        return true;
    }
    return false;
}

equals方法含义按需要重写,但需要满足Java规范:

在Java规范中,对equals方法的使用必须遵循以下几个原则: 1)自反性。对于任何非空引用值x,x. equals(x)都应返回true。 2)对称性。对于任何非空引用值x和y,当且仅当y. equals(x)返回true时,x.equals(y)才应返回true。 3)传递性。对于任何非空引用值x、y和z,如果x. equals(y)返回true,并且y.equals(z)返回true,那么x. equals(z)应返回true。 4)一致性。对于任何非空引用值x和y,多次调用x. equals(y)始终返回true或始终返回false,前提是对象上equals比较中所用的信息没有被修改。对于任何非空引用值x,x. equals(null)都应返回false。 对于任何非空引用值x,x. equals(null)都应返回false。

3 hashCode方法

hashCode是一个本地方法,用来加快equals比较,但两个不同对象的哈希值难免有冲突,hashCode和equals的关系如下:

如果equals返回true,则hashCode一定相等; 如果equals返回false,则hashCode可能相等。 也就是说如果hashCode不相等,那么equals一定不相等。注:Object中的hashCode方法返回的是对象的内存地址,有特殊要求可重写。

代码语言:java
复制
@IntrinsicCandidate
public native int hashCode();

hashCode主要用于Map、Set等容器中,当向容器添加元素时需要去一个个比较是否有相等的元素,直接调用equals效率太慢。可以先比较hashCode,如果hashCode不一样则equals必然返回false,如果hashCode一样再调用equals比较。

image.png
image.png

4 wait

4.1 wait原理

wait方法也是Object类本地方法,一般用于synchronize代码块中,作用是释放锁并阻塞线程,唤醒方法是notify/notifyAll。

它是由JVM的监视器机制实现,ObjectMonitor中包含有:

  1. EntryList:保存阻塞线程,满足所有条件,只差CPU,一般被notify/notifyAll唤醒的线程会从WaitSet进入EntryList,线程具备了抢夺监视器的资源,状态从WAITING变为BLOCKED;
  2. WaitSet:保存等待线程,线程还差某个条件没满足,等待被notify;
  3. Owner:当前获取监视器的线程,EntryList中线程抢夺到监视器后,状态就会从BLOCKED变为RUNNABLE。
Monitor监视器
Monitor监视器
代码语言:java
复制
public final void wait() throws InterruptedException {
    wait(0L);
}

public final void wait(long timeoutMillis) throws InterruptedException {
    long comp = Blocker.begin();
    try {
        wait0(timeoutMillis);
    } catch (InterruptedException e) {
        Thread thread = Thread.currentThread();
        if (thread.isVirtual())
            thread.getAndClearInterrupt();
        throw e;
    } finally {
        Blocker.end(comp);
    }
}

// final modifier so method not in vtable
private final native void wait0(long timeoutMillis) throws InterruptedException;

public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
    if (timeoutMillis < 0) {
        throw new IllegalArgumentException("timeoutMillis value is negative");
    }

    if (nanos < 0 || nanos > 999999) {
        throw new IllegalArgumentException(
                            "nanosecond timeout value out of range");
    }

    if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
        timeoutMillis++;
    }

    wait(timeoutMillis);
}

4.2 sleep原理

sleep方法是Thread类方法,调用了sleep0本地方法,作用是不释放锁但阻塞线程,本质上调用了操作系统的sleep系统调用。sleep将线程状态修改为阻塞态,由时钟中断唤醒线程,修改为就绪态后,重新被调度。

代码语言:java
复制
public static void sleep(long millis) throws InterruptedException {
    if (millis < 0) {
        throw new IllegalArgumentException("timeout value is negative");
    }

    if (currentThread() instanceof VirtualThread vthread) {
        long nanos = MILLISECONDS.toNanos(millis);
        vthread.sleepNanos(nanos);
        return;
    }

    if (ThreadSleepEvent.isTurnedOn()) {
        ThreadSleepEvent event = new ThreadSleepEvent();
        try {
            event.time = MILLISECONDS.toNanos(millis);
            event.begin();
            sleep0(millis);
        } finally {
            event.commit();
        }
    } else {
        sleep0(millis);
    }
}

private static native void sleep0(long millis) throws InterruptedException;

4.3 await原理

await方法是ConditionObject/ReentrantLock类的方法,作用是释放锁并阻塞线程,唤醒方法是signal/signalAll。await是Java层面实现的,条件队列相当于等待队列,AQS同步队列相当于阻塞队列,线程调用await就会进入条件队列,当被signal唤醒后就进入同步队列等待获取锁。

await具体细节请看Java多线程:条件变量

代码语言:java
复制
public final void await() throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    ConditionNode node = new ConditionNode();
    int savedState = enableWait(node);//加入条件队列
    LockSupport.setCurrentBlocker(this); // for back-compatibility,将AQS对象设置到thread中
    boolean interrupted = false, cancelled = false, rejected = false;
    while (!canReacquire(node)) {//如果被唤醒进入同步队列后就可以跳出循环
        if (interrupted |= Thread.interrupted()) {
            if (cancelled = (node.getAndUnsetStatus(COND) & COND) != 0)
                break;              // else interrupted after signal
        } else if ((node.status & COND) != 0) {
            try {
                if (rejected)
                    node.block();
                else
                    ForkJoinPool.managedBlock(node);//阻塞线程,最终会调用LockSupport.park()
            } catch (RejectedExecutionException ex) {
                rejected = true;
            } catch (InterruptedException ie) {
                interrupted = true;
            }
        } else
            Thread.onSpinWait();    // awoke while enqueuing
    }
	//被唤醒
    LockSupport.setCurrentBlocker(null);
    node.clearStatus();//
	//lock.lock()方法:acquire(null, arg, false, false, false, 0L);
	//重新获取锁时已原来的savedState
    acquire(node, savedState, false, false, false, 0L);//重新获取锁,此时该节点已经进入了同步队列,有可能直接tryAcquire成功跳出循环,也可能需要两次循环修改node.status为WAITING、park。
    if (interrupted) {
        if (cancelled) {
            unlinkCancelledWaiters(node);
            throw new InterruptedException();
        }
        Thread.currentThread().interrupt();
    }
}

5 附录

代码语言:java
复制
public class Object {

    @IntrinsicCandidate
    public Object() {}

    @IntrinsicCandidate
    public final native Class<?> getClass();//返回类对象用于反射

    @IntrinsicCandidate
    public native int hashCode();

    public boolean equals(Object obj) {
        return (this == obj);
    }

    @IntrinsicCandidate
    protected native Object clone() throws CloneNotSupportedException;

    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

    @IntrinsicCandidate
    public final native void notify();

    @IntrinsicCandidate
    public final native void notifyAll();

    public final void wait() throws InterruptedException {
        wait(0L);
    }

    public final void wait(long timeoutMillis) throws InterruptedException {
        long comp = Blocker.begin();
        try {
            wait0(timeoutMillis);
        } catch (InterruptedException e) {
            Thread thread = Thread.currentThread();
            if (thread.isVirtual())
                thread.getAndClearInterrupt();
            throw e;
        } finally {
            Blocker.end(comp);
        }
    }

    // final modifier so method not in vtable
    private final native void wait0(long timeoutMillis) throws InterruptedException;

    public final void wait(long timeoutMillis, int nanos) throws InterruptedException {
        if (timeoutMillis < 0) {
            throw new IllegalArgumentException("timeoutMillis value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0 && timeoutMillis < Long.MAX_VALUE) {
            timeoutMillis++;
        }

        wait(timeoutMillis);
    }
    @Deprecated(since="9", forRemoval=true)
    protected void finalize() throws Throwable { }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 大纲
  • 2 equals方法
  • 3 hashCode方法
  • 4 wait
    • 4.1 wait原理
      • 4.2 sleep原理
        • 4.3 await原理
        • 5 附录
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档