Java多線程學習筆記(一)

1、什麼是多線程

首先是多線程的概念:
多線程

多線程是異步的,和單任務不一樣,並不必定按照代碼的執行順序(上圖左)來運行,而是交錯佔用CPU運行(上圖右);app

2、如何使用多線程

 JAVA多線程有兩種實現方式:一、繼承Thread類; 二、實現Runnable接口異步

其中實現Runnable接口是Java多線程的主要實現方法,由於JAVA的單繼承特性,一旦繼承了Thread類,就不能再繼承別的類。而JAVA類能夠繼承多個接口。
ide

一、繼承Thread類實現方法:

public class Thread extends Thread {
    @Override
    public void run(){
        //super.run(); 調用父類的run方法
        System.out.println("success!");
    }
}

public class Run {
    public static void main(String[] args) {
        Thread a = new Thread();
        a.start();
        System.out.println("end!");
    }
}

其中 @Override 是JAVA註解,代碼重寫一個父類的函數,繼承Thread類實現多線程,必須重寫 run() 方法。函數

問題一:爲何要寫 super.run();既然是重寫父類的 run() 方法爲何還要寫 super.run() 呢?ui

首先是 Thread run()方法 源碼:this

 //Thread類重寫了Runnable接口的run()方法。
//該run()方法首先判斷當前是否有Runnable的實現target存在。 若是存在就執行target.run()

private Runnable target;
@Override
public void run() { if (target != null) { target.run(); } }

原來Thread類也是實現了Runnable接口;在run()方法中,首先會檢查target是否爲空,若是不是,則執行該target的run()方法。spa

首先上結論:.net

一、無論傳入的Target是否爲空,首先都會執行Thread本身的run()方法。若是重寫了該方法且該方法中沒有super.run(),那麼是永遠不會調用Runnable實現的run()方法;線程

二、若是沒有重寫該方法,則會去判斷target是否爲空,以此來決定調用target實現的run()方法;

三、若是重寫了該方法,且該方法中有super.run(),在執行完該語句以前的全部代碼後,會判斷target是否爲空,以此來決定調用target實現的run()方法

具體實驗: https://blog.csdn.net/guguituzi/article/details/44593863

因此,super.run();正常狀況下能夠不寫,可是我看到是書上都習慣性帶上 super.run() ,知道爲何的小夥伴很是感謝可以給我留言告訴我答案。

問題二: .start() 源碼

/*  JVM調用此線程的run方法。*/

 public synchronized void start() {
        /**
         * This method is not invoked for the main method thread or "system"
         * group threads created/set up by the VM. Any new functionality added
         * to this method in the future may have to also be added to the VM.
         *
         * A zero status value corresponds to state "NEW".
         */
        //此判斷當前線程只能被啓動一次,不能被重複啓動
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        /* Notify the group that this thread is about to be started
         * so that it can be added to the group's list of threads
         * and the group's unstarted count can be decremented. */
        /*通知組該線程即將啓動
          *這樣它就能夠添加到組的線程列表中
         *而且該組的未啓動計數能夠遞減。*/
        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() 的順序,不表明線程的執行順序!

二、實現Runnable接口的實現方法:

public class Thread_2 implements Runnable{
    @Override
    public void run(){
        System.out.println("i'm running!...");
    }
}

實現原理和繼承Thread相似,再也不贅述。

相關文章
相關標籤/搜索