《JAVA源码分析》:Thread

JAVA Thread 源码分析

sleep(long millis, int nanos) 方法

源码如下:

public static void sleep(long millis, int nanos)
    throws InterruptedException {
        if (millis < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

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

        if (nanos >= 500000 || (nanos != 0 && millis == 0)) {
            millis++;
        }

        sleep(millis);
    }

从源码中可以看到,nanos参数是没有用到的,也就是说,sleep只能精确到 毫秒级。

而sleep(millis)的方法如下:

public static native void sleep(long millis) throws InterruptedException;

这个方法是一个native方法,即一个原生态的方法,原生态的方法是利用其它语言来实现的。这是因为JAVA是没法和硬件底层打交道。只能委托给其它语言来实现。

run方法是如何被调用的

写过线程的我们都知道,我们经常看到这样的代码

new SubThread().start()`;//subThread 是继承Thread的子类

或者是

`new Thread(new SubRunnable()).start()`;//SubRunnable是实现Runnable的类。`

当我们开启一个线程的时候,并不是直接去调用run方法,而是调用start()方法,start方法会自动给我们调用对象的run方法。

因此,我们先看start()方法。

start()方法的源码如下:

public synchronized void start() {

        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        group.add(this);

        boolean started = false;
        try {
            start0();
            started = true;//线程开启的标志
        } finally {
            try {
                if (!started) {
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */
            }
        }
    }

从上面的代码可以看出,start()方法主要是调用了一个start0()这个方法。而start0() 是一个原生态方法,如下:

private native void start0();

原生态的方法是由其它的语言实现,我们看不到里面的具体实现。

下面我们来看Thread类中的run()方法。

由于Thread类是实现Runnable接口。Runable接口中只有一个抽象的run方法,如下:

public abstract void run();

因此,Thread就重写了此run方法,源码如下:

@Override
    public void run() {
        if (target != null) {
            target.run();//target是一个Runnable的引用
        }
    }`

从源码中可以看出,如果target存在,则执行target的run方法,否则什么也不做。也就是说Thread的run()方法总是先被调用,然后调用target(构造函数中的Runnable对象)的run()方法。

其它的部分,明天再来完成

你可能感兴趣的:(java,thread,源码,线程)