The Java base Object class

The Object class is the parent of all classes. For any class in Java, it is a subclass of Object.

Object class source:

public class Object {

    // Register the necessary information locally
    private static native void registerNatives(a);
    static {
        registerNatives();
    }
    // Get the bytecode file object. Is unique to each class
    public finalnative Class<? >getClass(a);

    // By default, the memory address of the object is returned
    public native int hashCode(a);

    The // equals method compares the hashCode values of the two objects by default
    // So the equals and hashCode methods are usually overridden
    public boolean equals(Object obj) {
        return (this == obj);
    }

    // The permission modifier is left to subclasses to override.
    // The clone method will be mentioned here later.
    protected native Object clone(a) throws CloneNotSupportedException;

    // The toString method prints the class name +@+ the hexadecimal integer of the object.
    // This method is generally rewritten
    public String toString(a) {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

    // These methods appear in the Object class because Object is the parent class of all objects.
    // Then the following methods must be related to objects.
    // See a keyword repeatedly through the method comment: monitor object monitor
    // Use the object as a monitor, and all threads will loot the monitor. If you get it, you do it. If you don't get it, you go to the blocking level
    / / section. Notify, notifyAll, and wait methods are typically used in a synchronized code block or method.
    // Note that the object monitor must be the same and must be used to call methods to wake up other threads, etc.

    // notify is a thread that wakes up randomly on the object monitor
    It is also important to note that calling the entire method does not immediately release the object monitor, but rather waits for the following logic to complete.
    public final native void notify(a);

    // notifyAll is to wake up all threads on the object monitor. At this point, there will be contention for object monitors
    public final native void notifyAll(a);

    // This method refers to waiting on the object monitor to obtain access to the object monitor. When the time expires, it will automatically try again
    // During this time, the lock object that will be released has entered the timeout wait state.
    public final native void wait(long timeout) throws InterruptedException;

    	// All the above methods are called
        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(a) throws InterruptedException {
        wait(0);
    }

    // Subclass override method. This is the end work done before the garbage collection mechanism.
    protected void finalize(a) throws Throwable {}Copy the code

So I prefer to think of the object monitor as a data structure to hold threads. When a thread completes execution or releases the object monitor during execution, the object monitor randomly selects a thread to execute the logic in the Syncronized code block.

For each thread, there will be a register to record the thread state of the thread, and then the execution of the thread to restore.

At the same time, it should be noted that the native keyword modification method is the local way, and the bottom layer is implemented through C and C ++.

So a method without a method body is not necessarily an abstract method; Abstract methods must have no method body;

2. Code demonstration

To demonstrate communication between threads using the Wait and notify methods of the Object class:

2.1, not

public class Foodie extends Thread {
    private BaoZi baoZi;

    public Foodie(BaoZi baoZi) {
        this.baoZi = baoZi;
    }

    @Override
    public void run(a) {
        synchronized (baoZi) {
            for(; ;) { synchronized (baoZi) {// If there is a bun, then start to enter the waiting state; If there are no baozi, then start making baozi
                    if (baoZi.getFlag() == false) {
                        System.out.println("No buns. Tell the chef to wrap the buns.");
                        try {
                            // The thread waits on the object monitor
                            baoZi.wait();
                        } catch(InterruptedException e) { e.printStackTrace(); }}// The program is executed at this location, indicating that there is no bun. So start making the buns
                    baoZi.setFlag(false);
                    baoZi.notify();
                }
            }
        }
    }
}

Copy the code
public class Cook extends Thread {
    private BaoZi baoZi;

    public Cook(BaoZi baoZi) {
        this.baoZi = baoZi;
    }

    @Override
    public void run(a) {
        synchronized (baoZi) {
            for(; ;) {// If there are baozi, then consume; If not, wait
                if (baoZi.getFlag() == true) {
                    try {
                        System.out.println("Baozi, start to wait for consumers to consume.......");
                        baoZi.wait();
                    } catch(InterruptedException e) { e.printStackTrace(); }}// The program has reached this point
                // system.out.println (" start making buns, then change the buns to no buns ");
                baoZi.setFlag(true); baoZi.notify(); }}}}Copy the code
public class BaoZi {
    // When the FLAG is true, it means there are buns; When false, it means there is no bun
    private boolean flag;

    public Boolean getFlag(a) {
        return flag;
    }

    public void setFlag(Boolean flag) {
        this.flag = flag; }}Copy the code
public class DemoTwo {
    public static void main(String[] args) {
        BaoZi baoZi = new BaoZi();
        Cook cook = new Cook(baoZi);
        Foodie foodie = newFoodie(baoZi); cook.start(); foodie.start(); }}Copy the code

You can see the output from the console in the example above:

No steamed stuffed bun, inform the chef to pack steamed stuffed bun steamed stuffed bun, began to wait for consumers to consume....... No steamed stuffed bun, inform the chef to pack steamed stuffed bun steamed stuffed bun, began to wait for consumers to consume.......Copy the code

2.2, Demo2

/** * print ABC */ using three threads alternately
public class DemoOne {

    private static int num = 1;

    public static void main(String[] args) {

        new Thread(() -> {
            while (true){
                synchronized (DemoOne.class) {
                    while(num ! =1) {
                        try {
                            DemoOne.class.wait(a); } catch (InterruptedException e) { e.printStackTrace(a); } } num=2;
                    DemoOne.class.notifyAll(a); System.out.println("A"); }}}).start(a);new Thread(() -> {
            while (true){
                synchronized (DemoOne.class) {
                    while(num ! =2) {
                        try {
                            DemoOne.class.wait(a); } catch (InterruptedException e) { e.printStackTrace(a); } } num=3;
                    DemoOne.class.notifyAll(a); System.out.println("B"); }}}).start(a);new Thread(() -> {
            while (true){
                synchronized (DemoOne.class) {
                    while(num ! =3) {
                        try {
                            DemoOne.class.wait(a); } catch (InterruptedException e) { e.printStackTrace(a); } } num=1;
                    DemoOne.class.notifyAll(a); System.out.println("C"); }}}).start(a); try { Thread.sleep(Integer.MAX_VALUE);
        } catch (InterruptedException e) {
            e.printStackTrace(a); }}}Copy the code

3. Cloning methods

The cloning method mentioned above. In fact, cloning is equivalent to a copy method. To make it easier to write our code.

References to objects such as strong and weak virtual objects are essentially determined by the GC algorithm instead of being manually freed. When GC is used for collection, what time period is required for collection.

A journey of a thousand miles begins with a single step. A thousand miles is a short step

Tag: [Java Basics]