Java多線程專題之線程類和接口入門
前言
大家好,一直以來我都本著用最通俗的話理解核心的知識點, 我認為所有的難點都離不開 「基礎(chǔ)知識」 的鋪墊。目前正在出一個Java多線程專題長期系列教程,從入門到進階, 篇幅會較多, 喜歡的話,給個關(guān)注?? ~
適合人群
- 有一定的Java基礎(chǔ)
- 想學(xué)習或了解多線程開發(fā)
- 想提高自己的同學(xué)
- 「大佬可以繞過 ~」
背景
之前給大家講了一些框架的使用,這些都屬于業(yè)務(wù)層面的東西,你需要熟練掌握它并在項目中會運用它即可,但這些對自身技術(shù)的積累是遠遠不夠的,如果你想要提高自己,對于語言本身你需要花更多的時間去挖掘而不是局限于框架的使用,所以之前為什么跟大家一直強調(diào)基礎(chǔ)的重要性,框架可以千變?nèi)f化,層出不窮,但是基礎(chǔ)它是不變的,不管是學(xué)java還是前端或者是其它語言, 這一點大家還是需要認清的。
接下來的幾期會專門講多線程這一塊,篇幅會較多,耐心看完你一定會有收獲~
情景回顧
上期帶大家學(xué)習了什么是進程什么是線程,理解了它們的基本概念,本期正式學(xué)習Java多線程開發(fā),本節(jié)主要帶大家入門,認識一些常用的類和接口,我們一起來看一下吧~
Thread 類
在JDK中,提供了一個Thread類,我們只需要繼承這個類,就可以實現(xiàn)多線程:
public class ThreadTest {
public static class MyThread extends Thread {
public void run() {
System.out.println("hello 2");
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
// 啟用線程 (不調(diào)用是沒法啟動的)
myThread.start();
System.out.println("hello 1");
}
}
最后結(jié)果輸出:
hello 1
hello 2
我們可以發(fā)現(xiàn)hello2明明在上面運行,為啥最后輸出,因為它啟動的是獨立的線程執(zhí)行,所以不會造成阻塞,所以調(diào)用start的時候,后續(xù)代碼會繼續(xù)執(zhí)行,無需等待hello2的結(jié)果。
那么我可以調(diào)用多次start嗎?這樣是不是可以多開幾個線程,我們試試看:
public static void main(String[] args) {
MyThread myThread = new MyThread();
myThread.start();
System.out.println("hello 1");
myThread.start();
}
運行一下:
Exception in thread "main" java.lang.IllegalThreadStateException
at java.lang.Thread.start(Thread.java:710)
at com.thread.base.ThreadTest.main(ThreadTest.java:23)
好家伙,直接報錯,那么原因是什么呢?
為什么start()不可以調(diào)用多次
首先我們要明白,Java中,線程是不允許啟動兩次的,啟動第二次就會拋出IllegalThreadStateException的異常。那么這個異常為啥拋呢?我們只要找到start方法中拋這個異常的地方不就好了,下面我們看下源碼:
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();
....
}
好家伙,點進去就找到了,說明,每次調(diào)用的時候,首先都會判斷 threadStatus 是否為0。這個0代表的是線程NEW狀態(tài),也就是說第二次調(diào)用線程可能會處于非NEW狀態(tài)。其實這里涉及到線程生命周期的概念了,先不給大家講解, 后邊給大家講,這一節(jié),我們先入門。
Runnable 接口
我們還可以通過實現(xiàn)Runnable接口,來開啟多線程。我們來看一下:
public class RunnableTest {
public static class MyThread implements Runnable {
public void run() {
System.out.println("hello 2");
}
}
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
System.out.println("hello 1");
}
}
看下輸出:
hello 1
hello 2
new Thread,其實還有通過java8的特性表達式,還可以這樣使用:
new Thread(() -> {
System.out.println("hello3");
}).start();
這樣也可以開啟一個多線程。
結(jié)束語
本期到這里就結(jié)束了, 總結(jié)一下,本節(jié)主要講了Thread類和Runnable接口,以及帶大家實際操作了一下,大家可以自己多試試。