Java線程演示樣例 - 繼承Thread類和實現Runnable接口
進程(Process)和線程(Thread)是程序執行的兩個基本單元。
Java並發編程很多其它的是和線程相關。
進程
進程是一個獨立的執行單元,可將其視為一個程序或應用。然而,一個程序內部同事還包括多個進程。
Java執行時環境就是一個單獨的進程,在它內部還包括了作為進程的各種類和程序。
線程
能夠將線程看做輕量級的進程。
線程存在於進程其中,須要的資源開銷較小。同一進程中的線程共享進程的資源。
Java多線程
每個Java引用都僅僅要有一個線程 - 主線程(main thread)。盡管後臺還執行著更多的線程,如內存管理、系統管理、信號處理等等,可是從應用程序的角度來講,main是第一個線程,我們能夠從它開始創建多個線程。
線程的長處
1. 與進程相比,線程時輕量級的。創建線程的時間開銷和資源開銷都非常小。
2. 同一進程的線程共享進程的數據和代碼。
3. 線程間上下文切換的開銷通常小於進程。
4. 與進程間通信相比,線程間通信更為方便。
在編程中。Java提供了兩種創建線程的方式:
1. 實現java.lang.Runnable接口
2. 繼承java.lang.Thread類
Java線程演示樣例 - 實現Runnable接口
為了使類能執行,我們須要實現java.lang.Runnable接口,並在public void run()方法中提供實現。同一時候。還須要創建一個Thread對象,並將實現了Runnable接口的類作為參數闖入,這樣才幹調用start()
以下就是一個實現了Runnable接口的Java類。
HeavyWorkRunnable.java
package com.journaldev.threads; public class HeavyWorkRunnable implements Runnable { @Override public void run() { System.out.println("Doing heavy processing - START " + Thread.currentThread().getName()); try { Thread.sleep(1000); //Get database connection, delete unused data from DB doDBProcessing(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Doing heavy processing - END " + Thread.currentThread().getName()); } private void doDBProcessing() throws InterruptedException { Thread.sleep(5000); } }
Java線程演示樣例 - 繼承Thread類
能夠通過集成java.lang.Thread類並重寫run()方法來創建自己的線程類。我們能夠創建線程類的對象,並調用start()方法來運行定義好的run方法。
以下的樣例演示了怎樣集成Thread類。
MyThread.java
package com.journaldev.threads; public class MyThread extends Thread { public MyThread(String name) { super(name); } @Override public void run() { System.out.println("Doing heavy processing - START " + Thread.currentThread().getName()); try { Thread.sleep(1000); //Get database connection, delete unused data from DB doDBProcessing(); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("Doing heavy processing - END " + Thread.currentThread().getName()); } private void doDBProcessing() throws InterruptedException { Thread.sleep(5000); } }
以下的測試程序演示了怎樣創建並運行線程。
ThreadRunExample.java
package com.journaldev.threads; public class ThreadRunExample { public static void main(String[] args) { Thread t1 = new Thread(new HeavyWorkRunnable(), "t1"); Thread t2 = new Thread(new HeavyWorkRunnable(), "t2"); System.out.println("Starting Runnable threads"); t1.start(); t2.start(); System.out.println("Runnable Threads has been started"); Thread t3 = new MyThread("t3"); Thread t4 = new MyThread("t4"); System.out.println("Starting MyThreads"); t3.start(); t4.start(); System.out.println("MyThreads has been started"): } }上面的Java程序輸出結果例如以下:
Starting Runnable threads Runnable Threads has been started Doing heavy processing - START t1 Doing heavy processing - START t2 Starting MyThreads MyThread - START Thread-0 MyThreads has been started MyThread - START Thread-1 Doing heavy processing - END t2 MyThread - END Thread-1 MyThread - END Thread-0 Doing heavy processing - END t1一旦我們啟動線程,它的運行就依賴於操作系統的時間分片。我們無法控制線程的運行。
然而,我們卻能夠設置線程的優先級,但這無法保證高優先級的線程將會優先運行。
比較Runnable和Thread
假設你的類不只作為一個線程來執行,而是須要提供很多其它的功能,那麽,你就應該實現Runnable接口。假設你的類的目標只不過作為線程來執行。你能夠直接繼承Thread類。
相比繼承Thread類,實現Runnable接口更好一些,由於Java支持多接口實現。一旦你的類繼承了Thread類。那它就無法再繼承其它類了。
技巧:你可能註意到了。線程並不返回不論什麽值。但假設我們希望線程在完畢處理工作後能返回處理結果給客戶程序的話。能夠參考文章《Java Callable Future》。
更新:從Java 8開始,Runnable議程誠意一個功能性接口。我們能夠使用lambda表達式來實現它,而非使用匿名類。詳情請見《Java 8 Lambda Expressions Tutorial》。
原文地址:Java Thread Example - Extending Thread Class and Implementing Runnable Interface
Java線程演示樣例 - 繼承Thread類和實現Runnable接口