一、使用Thread類啟動線程
Java中啟動線程的最簡單方法就是使用Thread類。Thread類提供了很多啟動線程的方法,但是其中最常用的方法是調用Thread對象的start()方法。
public class MyThread extends Thread { public void run() { //線程執行代碼 } } public class Main { public static void main(String args[]) { MyThread myThread = new MyThread(); myThread.start(); } }
上述代碼中,MyThread類繼承自Thread類,並且重寫了run()方法。在main()方法中,通過創建MyThread對象myThread,並調用其start()方法啟動線程。
二、使用Runnable接口啟動線程
除了使用Thread類外,Java還提供了另一種啟動線程的方法,那就是實現Runnable接口。與Thread類不同的是,Runnable接口只定義了run()方法,需要通過Thread類的構造函數將其與Thread對象關聯起來。
public class MyRunnable implements Runnable { public void run() { //線程執行代碼 } } public class Main { public static void main(String args[]) { MyRunnable myRunnable = new MyRunnable(); Thread thread = new Thread(myRunnable); thread.start(); } }
上述代碼中,MyRunnable類實現了Runnable接口,並重寫了run()方法。在main()方法中,創建MyRunnable對象myRunnable,並將其關聯到Thread對象上,最後啟動線程。
三、使用匿名內部類啟動線程
除了以上兩種方法外,Java還提供了第三種啟動線程的方法,那就是使用匿名內部類。這種方法可以讓代碼更加簡潔,但是也比較難以閱讀。
public class Main { public static void main(String args[]) { Thread thread = new Thread(new Runnable() { public void run() { //線程執行代碼 } }); thread.start(); } }
上述代碼中,通過創建一個匿名內部類實現Runnable接口,並在其中重寫run()方法。然後將該對象關聯到Thread對象上,並啟動線程。
四、使用線程池啟動線程
線程池是一種常用於控制多線程的技術,通過線程池可以避免直接使用Thread類造成的頻繁創建和銷毀線程的開銷。在Java中,可以使用Executor框架提供的線程池來啟動線程。
public class MyRunnable implements Runnable { public void run() { //線程執行代碼 } } public class Main { public static void main(String args[]) { ExecutorService executorService = Executors.newFixedThreadPool(10); for(int i=0; i<100; i++) { executorService.execute(new MyRunnable()); } executorService.shutdown(); } }
上述代碼中,創建了一個固定大小的線程池。在循環中,使用execute()方法提交100個MyRunnable對象,由線程池中的線程執行。最後通過shutdown()方法關閉線程池。
五、線程啟動順序的不確定性
無論採用哪種方法啟動線程,都不存在確定性的啟動順序。線程的順序是由操作系統調度決定的,開發人員不能對其進行干涉。
在以下代碼中,無論線程A和B的start()方法誰先被執行,線程的啟動順序並不能確定。
public class Main { public static void main(String args[]) { Thread threadA = new Thread(new Runnable() { public void run() { //線程A執行代碼 } }); Thread threadB = new Thread(new Runnable() { public void run() { //線程B執行代碼 } }); threadA.start(); threadB.start(); } }
六、線程啟動的重複性
Thread對象的start()方法只能被調用一次。如果嘗試對同一個Thread對象調用多次start()方法,則會在第二次調用時拋出IllegalThreadStateException異常。
public class MyThread extends Thread { public void run() { //線程執行代碼 } } public class Main { public static void main(String args[]) { MyThread myThread = new MyThread(); myThread.start(); myThread.start(); //會拋出IllegalThreadStateException異常 } }
七、線程啟動的安全性
在多線程環境下,需要考慮線程啟動的安全性。如果多個線程同時對同一個Thread對象調用start()方法,會導致該線程被多次啟動,從而導致不確定的行為。
在以下代碼中,如果多個線程都同時調用start()方法,線程A就有可能被多次啟動,並導致不同步的問題。
public class Main { private static Thread threadA = new Thread(new Runnable() { public void run() { //線程A執行代碼 } }); public static void main(String args[]) { Thread threadB = new Thread(new Runnable() { public void run() { threadA.start(); } }); Thread threadC = new Thread(new Runnable() { public void run() { threadA.start(); } }); threadB.start(); threadC.start(); } }
為了確保線程的啟動安全性,在多線程環境下應該盡量避免對同一個Thread對象調用start()方法。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/270682.html