iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 15
0

以上的文章內容都是屬於單執行緒程式,也就是啟動的程式從main()程式進入點開始至結束只有一個流程,有時候需要設計程式可以擁有多個流程,也就是所謂的多執行緒。

在了解何謂Java中的執行緒之前,我們必須要先知道Program程式、Process程序、Thread執行緒。

Program
Program 意旨軟體工程師在 IDE 所寫的程式碼(code),這些程式碼還尚未載入記憶體。我們也可以想像成軟體開發者就如同建築師,要設計一座工廠,而這座工廠要如何建造、規劃的藍圖就是 Program。

Process
Process 指已經執行並且被記憶體載入的 Program ,Program的每一行程式碼隨時都有可能被CPU執行。白話來說,當我們點開應用程式時,就是將 Program 活化成 Process,賦予其載入到記憶體的機會。

Thread
Process 是 Thread 的容器(Container),在同一個 Process 中可以存在很多個 Thread ,以聊天室 Process 為例,可以同時接受對方傳來的訊息以及發送自己的訊息給對方,就是同個 Process 中不同 Thread的功勞。

而所謂的多執行緒程式(multithreading)的概念就是,當你的程式有很多 thread 的時候,作業系統會把它排進一個 Queue,然後每個 thread 就會排隊輪流執行,優先權高的可能會執行比較久,但優先權低的也會執行到,只是可能會一直被插隊。

https://ithelp.ithome.com.tw/upload/images/20200928/20128925l8TAHyREY2.png
(圖片取至網路)

然後讓我們來看一下執行緒的生命週期~
https://ithelp.ithome.com.tw/upload/images/20200928/20128925xaaZfV4EML.jpg

當 new 一個 thread 物件並執行 start() method 後,會進入 Runnable 狀態,而 JVM 中會有一個 scheduler 專門負責處理所有狀態為 Runnable 的 thread 排程,因此即使狀態是 Runnable 的 thread,也必須要被排入執行才會真的執行 run() method 中的程式。而 thread 之間工作切換的速度很快,因此看來就像在同時執行一般。

而在Java中,實作多執行緒的方法有兩種:

第一種實現方法 — Thread 類別
Thread類別實作了Runnable介面。Java 的 Thread 被定義在 java.lang.Thread,會從物件裡的 run() 開始執行
執行完了那個 thread 就結束。
Oracle官方文檔 -
https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html

假設我們今天要寫五個可以印出我是誰的程式,我們可以把它獨立成五個thread:

public class ThreadExample extends Thread {

	private String x;

    public ThreadExample(int x){
        // turn to string
        this.x = String.valueOf(x);
    }

    @Override
    public void run(){
        System.out.println("Hello I'm " + x);
    }


    public static void main(String[] args){
    	ThreadExample t1 = new ThreadExample(1);
    	ThreadExample t2 = new ThreadExample(2);
    	ThreadExample t3 = new ThreadExample(3);
    	ThreadExample t4 = new ThreadExample(4);
    	ThreadExample t5 = new ThreadExample(5);
        
        // 新增 5 個 thread
        t1.setPriority(1);
        t2.setPriority(2);
        t3.setPriority(3);
        t4.setPriority(4);
        t5.setPriority(10);
     
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }

結果 -
https://ithelp.ithome.com.tw/upload/images/20200928/20128925usL9q1veUX.png

第二種實現方法 — Runnable
還有一種方法可以讓 object 擁有 Multi-Thread 的能力,則是實作Runnable interface,並實作其中的 run() method,寫法與Thread大同小異,主要只是繼承 class 與實作 interface 的差異而已。

不過建議多使用實作 Runnable interface 的方式,如此一來可擁有 Multi-Thread 的功能,又保留了繼承其他 class 的彈性。

範例是用兩個thread印出三次水果 -

public class RunnableExample implements Runnable {
	private String name;
	 
	    public RunnableExample(String str) {
	    	name=str;
	    }
	 
	    public void run() {
		    for(int i=0;i<3;i++)
		    {
		      for(int j=0;j<100000000;j++);
		    	System.out.println(name+" is running..");
		    }
	    }
	 
	    
	public static void main(String[] args) throws InterruptedException {
		RunnableExample r1 = new RunnableExample("apple");
		RunnableExample r2 = new RunnableExample("banana"); 
		Thread t1 = new Thread(r1);
		Thread t2 = new Thread(r2);
		
		t1.start();
		t2.start();
      
	}

}

https://ithelp.ithome.com.tw/upload/images/20200928/20128925iUk8l18HDr.png

特別要注意的是Thread是類別,而Runnable是介面,使用上要特別注意。

除此之外,thread程式中也可以設置優先權,我們可以用Thread.setPriority(int)來設定優先權,priority可以設定 1 ~ 10,預設值是 5,數字越大優先權越高。優先權低不代表一定比較晚執行,只是代表他們同時競爭相同資源時,會先給優先權大的。

還有一些其他方法如,sleep()是讓執行緒休息一段時間 thr1.sleep(5000),Wait()是在執行後,必須使用notify()方法或notifyAll()方法或設定等待時間(wait(long time))喚醒在等待執行緒池中的執行緒

以上是今天的內容,see u tomorrow~


Hi, I am Grant.

個人部落格 - https://grantliblog.wordpress.com/
個人網站 - https://grantli-website.netlify.app/#/mainpage
我的寫作專題 - https://vocus.cc/user/5af2e9b5fd89780001822db4#


上一篇
Day14 - 輸入與輸出
下一篇
Day16 - 今晚來點JAVA佐題目吧!
系列文
30天手把手帶你跟JAVA變成好朋友 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言