java.lang.Object是所有类的父类,默认继承,而且java.lang包下的所有类都由编译器自动导入,不需要显示import,因为用的多,提前加载可以提高运行时速度。
"=="与equals的区别要看equals是如何重写的,在Object中两者意义等同,都是判断引用地址是否相同。在String中equals比较的是内容。
//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。
hashCode是一个本地方法,用来加快equals比较,但两个不同对象的哈希值难免有冲突,hashCode和equals的关系如下:
如果equals返回true,则hashCode一定相等; 如果equals返回false,则hashCode可能相等。 也就是说如果hashCode不相等,那么equals一定不相等。注:Object中的hashCode方法返回的是对象的内存地址,有特殊要求可重写。
@IntrinsicCandidate
public native int hashCode();
hashCode主要用于Map、Set等容器中,当向容器添加元素时需要去一个个比较是否有相等的元素,直接调用equals效率太慢。可以先比较hashCode,如果hashCode不一样则equals必然返回false,如果hashCode一样再调用equals比较。
wait方法也是Object类本地方法,一般用于synchronize代码块中,作用是释放锁并阻塞线程,唤醒方法是notify/notifyAll。
它是由JVM的监视器机制实现,ObjectMonitor中包含有:
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);
}
sleep方法是Thread类方法,调用了sleep0本地方法,作用是不释放锁但阻塞线程,本质上调用了操作系统的sleep系统调用。sleep将线程状态修改为阻塞态,由时钟中断唤醒线程,修改为就绪态后,重新被调度。
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;
await方法是ConditionObject/ReentrantLock类的方法,作用是释放锁并阻塞线程,唤醒方法是signal/signalAll。await是Java层面实现的,条件队列相当于等待队列,AQS同步队列相当于阻塞队列,线程调用await就会进入条件队列,当被signal唤醒后就进入同步队列等待获取锁。
await具体细节请看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();
}
}
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 删除。