Java中創(chuàng)建線程的核心方式有三種:實(shí)現(xiàn)runnable接口、繼承Thread類、使用executorservice。1.實(shí)現(xiàn)runnable接口是推薦方式,通過實(shí)現(xiàn)run()方法定義任務(wù),再由thread執(zhí)行,避免單繼承限制并解耦任務(wù)與線程;2.繼承thread類則直接重寫run()方法,雖簡單但不靈活且受限于單繼承;3.使用executorservice線程池可更高效管理線程,支持復(fù)用、提升性能和可維護(hù)性。線程啟動需調(diào)用start()而非run(),控制生命周期可用sleep()、yield()、join()、interrupt()等方法,stop()已廢棄。解決線程安全問題可通過synchronized、lock、原子類及線程安全集合類,需根據(jù)場景權(quán)衡性能與安全性。
Java中創(chuàng)建線程的核心在于定義一個(gè)任務(wù),然后讓線程去執(zhí)行這個(gè)任務(wù)。通常,我們會通過實(shí)現(xiàn)Runnable接口或繼承Thread類來實(shí)現(xiàn)。不過,隨著Java的發(fā)展,也出現(xiàn)了一些更簡潔的方式,比如使用ExecutorService。
實(shí)現(xiàn)Runnable接口,繼承Thread類,使用ExecutorService。
實(shí)現(xiàn)Runnable接口
這是最常見的方式,也是我個(gè)人比較推薦的方式。Runnable接口只有一個(gè)run()方法,我們需要做的就是實(shí)現(xiàn)這個(gè)方法,把需要在線程中執(zhí)行的代碼放在run()方法里。
立即學(xué)習(xí)“Java免費(fèi)學(xué)習(xí)筆記(深入)”;
public class MyRunnable implements Runnable { @Override public void run() { System.out.println("Runnable線程執(zhí)行中..."); } public static void main(String[] args) { Thread thread = new Thread(new MyRunnable()); thread.start(); } }
這樣做的好處是,你的類可以繼承其他的類,避免了Java單繼承的限制。而且,Runnable接口更關(guān)注任務(wù)的定義,將任務(wù)和線程本身解耦,使得代碼更加靈活。
繼承Thread類
這種方式很簡單,直接繼承Thread類,并重寫run()方法。
public class MyThread extends Thread { @Override public void run() { System.out.println("Thread線程執(zhí)行中..."); } public static void main(String[] args) { MyThread thread = new MyThread(); thread.start(); } }
雖然簡單,但是不推薦使用。因?yàn)镴ava是單繼承的,繼承了Thread類就不能繼承其他的類了。而且,這種方式將線程和任務(wù)耦合在一起,不夠靈活。
使用ExecutorService
ExecutorService是Java提供的線程池,可以更方便地管理線程。它可以復(fù)用線程,避免頻繁創(chuàng)建和銷毀線程的開銷。
import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ExecutorServiceExample { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(5); // 創(chuàng)建一個(gè)固定大小的線程池 for (int i = 0; i < 10; i++) { executor.execute(() -> { System.out.println("線程 " + Thread.currentThread().getName() + " 執(zhí)行中..."); }); } executor.shutdown(); // 關(guān)閉線程池 } }
ExecutorService提供了多種線程池實(shí)現(xiàn),比如newFixedThreadPool、newCachedThreadPool、newSingleThreadExecutor等,可以根據(jù)不同的場景選擇合適的線程池。使用線程池可以提高程序的性能和可維護(hù)性。
線程創(chuàng)建后如何啟動?
創(chuàng)建線程對象后,不能直接調(diào)用run()方法來啟動線程,而是要調(diào)用start()方法。start()方法會啟動一個(gè)新的線程,并在新的線程中執(zhí)行run()方法。如果直接調(diào)用run()方法,那么run()方法會在當(dāng)前線程中執(zhí)行,而不是創(chuàng)建一個(gè)新的線程。
如何控制線程的生命周期?
線程的生命周期包括新建、就緒、運(yùn)行、阻塞、死亡五個(gè)狀態(tài)。我們可以通過一些方法來控制線程的生命周期,比如:
- sleep():讓線程休眠一段時(shí)間。
- yield():讓線程放棄當(dāng)前CPU的執(zhí)行權(quán),讓給其他線程。
- join():等待其他線程執(zhí)行完畢。
- interrupt():中斷線程。
需要注意的是,stop()方法已經(jīng)被廢棄,不建議使用,因?yàn)樗赡軙?dǎo)致線程狀態(tài)不一致。
線程安全問題如何解決?
多線程并發(fā)訪問共享資源時(shí),可能會出現(xiàn)線程安全問題。常見的解決方案有:
- 使用synchronized關(guān)鍵字:可以保證同一時(shí)刻只有一個(gè)線程可以訪問被synchronized修飾的代碼塊或方法。
- 使用Lock接口:提供了比synchronized關(guān)鍵字更靈活的鎖機(jī)制。
- 使用原子類:提供了原子操作,可以保證操作的原子性。
- 使用線程安全的集合類:比如ConcurrentHashMap、CopyOnWriteArrayList等。
選擇合適的線程安全解決方案需要根據(jù)具體的場景進(jìn)行考慮。過度使用鎖可能會導(dǎo)致性能下降,而使用原子類或線程安全的集合類則可以提高程序的并發(fā)性能。