Java多線程的使用有三種方法:繼承Thread類、實現(xiàn)Runnable接口和使用Callable和Future創(chuàng)建線程。
一、繼承Thread類
實現(xiàn)方式很簡單,只需要創(chuàng)建一個類去繼承Thread類然后重寫run方法,在main方法中調用該類實例對象的start方法即可實現(xiàn)多線程并發(fā)。代碼:
public class MyThread extends Thread { @Override public void run(){ super.run(); System.out.println("執(zhí)行子線程..."); } }
測試用例:
public class Test { public static void main(String[] args) { MyThread myThread = new MyThread(); myThread.start(); System.out.println("主線程..."); } }
運行結果:
當然,這里的結果不代表線程的執(zhí)行順序,線程是并發(fā)執(zhí)行的,如果多運行幾次,打印順序可能會不一樣。多線程的運行過程中,CPU是以不確定的方式去執(zhí)行線程的,故運行結果與代碼的執(zhí)行順序或者調用順序無關,運行結果也可能不一樣。
免費視頻教程推薦:java學習視頻
這里還有一個需要注意的點就是main方法中應該調用的是myThread的start方法,而不是run()方法。調用start()方法是告訴CPU此線程已經(jīng)準備就緒可以執(zhí)行,進而系統(tǒng)有時間就會來執(zhí)行其run()方法。
而直接調用run()方法,則不是異步執(zhí)行,而是等同于調用函數(shù)般按順序同步執(zhí)行,這就失去了多線程的意義了。
二、實現(xiàn)Runnable接口
這種方式的實現(xiàn)也很簡單,就是把繼承Thread類改為實現(xiàn)Runnable接口。代碼如下:
public class MyRunnable implements Runnable { @Override public void run() { System.out.println("執(zhí)行子線程..."); } }
測試用例:
public class Test { public static void main(String[] args) { Runnable runnable = new MyRunnable(); Thread thread = new Thread(runnable); thread.start(); System.out.println("主線程運行結束!"); } }
運行結果:
運行結果沒啥好說的,這里main中可以看到真正創(chuàng)建新線程還是通過Thread創(chuàng)建:
Thread thread = new Thread(runnable);
這一步Thread類的作用就是把run()方法包裝成線程執(zhí)行體,然后依然通過start去告訴系統(tǒng)這個線程已經(jīng)準備好了可以安排執(zhí)行。
三、使用Callable和Future創(chuàng)建線程
上面的兩種方式都有這兩個問題:
1、無法獲取子線程的返回值;
2、run方法不可以拋出異常。
為了解決這兩個問題,我們就需要用到Callable這個接口了。說到接口,上面的Runnable接口實現(xiàn)類實例是作為Thread類的構造函數(shù)的參數(shù)傳入的,之后通過Thread的start執(zhí)行run方法中的內容。但是Callable并不是Runnable的子接口,是個全新的接口,它的實例不能直接傳入給Thread構造,所以需要另一個接口來轉換一下。
Java5提供了Future接口來代表Callable接口里call()方法的返回值,并為Future接口提供了一個實現(xiàn)類FutureTask,該實現(xiàn)類的繼承關系如圖所示:
可以看到,該實現(xiàn)類不僅實現(xiàn)了Future接口,還實現(xiàn)了Runnable接口,所以可以直接傳給Thread構造函數(shù)。
而關于FutureTask的構造函數(shù)如下:
所以這里面其實就是要比上一個方法再多一個轉換過程,最終一樣是通過Thread的start來創(chuàng)建新線程。有了這個思路,代碼就很容易理解了:
import java.util.concurrent.Callable; public class MyCallable implements Callable { int i = 0; @Override public Object call() throws Exception { System.out.println(Thread.currentThread().getName()+" i的值:"+ i); return i++; //call方法可以有返回值 } }
測試:
import java.util.concurrent.Callable; import java.util.concurrent.FutureTask; public class Test { public static void main(String[] args) { Callable callable = new MyCallable(); for (int i = 0; i < 10; i++) { FutureTask task = new FutureTask(callable); new Thread(task,"子線程"+ i).start(); try { //獲取子線程的返回值 System.out.println("子線程返回值:"+task.get() + "\n"); } catch (Exception e) { e.printStackTrace(); } } } }
執(zhí)行結果(部分):
相關文章教程推薦:java入門程序
Atas ialah kandungan terperinci java中實現(xiàn)多線程的幾種方式. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Alat AI Hot

Undress AI Tool
Gambar buka pakaian secara percuma

Undresser.AI Undress
Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover
Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Clothoff.io
Penyingkiran pakaian AI

Video Face Swap
Tukar muka dalam mana-mana video dengan mudah menggunakan alat tukar muka AI percuma kami!

Artikel Panas

Alat panas

Notepad++7.3.1
Editor kod yang mudah digunakan dan percuma

SublimeText3 versi Cina
Versi Cina, sangat mudah digunakan

Hantar Studio 13.0.1
Persekitaran pembangunan bersepadu PHP yang berkuasa

Dreamweaver CS6
Alat pembangunan web visual

SublimeText3 versi Mac
Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Untuk mengendalikan transaksi JDBC dengan betul, anda mesti terlebih dahulu mematikan mod komit automatik, kemudian melakukan pelbagai operasi, dan akhirnya melakukan atau mengembalikan semula hasilnya; 1. Panggil Conn.SetAutOcommit (palsu) untuk memulakan transaksi; 2. Melaksanakan pelbagai operasi SQL, seperti memasukkan dan mengemaskini; 3. Panggil Conn.Commit () jika semua operasi berjaya, dan hubungi conn.rollback () jika pengecualian berlaku untuk memastikan konsistensi data; Pada masa yang sama, cuba-dengan-sumber harus digunakan untuk menguruskan sumber, mengendalikan pengecualian dengan betul dan menutup sambungan untuk mengelakkan kebocoran sambungan; Di samping itu, adalah disyorkan untuk menggunakan kolam sambungan dan menetapkan mata simpan untuk mencapai rollback separa, dan menyimpan urus niaga sesingkat mungkin untuk meningkatkan prestasi.

Gunakan kelas dalam pakej Java.Time untuk menggantikan kelas lama dan kelas kalendar; 2. Dapatkan tarikh dan masa semasa melalui LocalDate, LocalDateTime dan Tempatan Tempatan; 3. Buat tarikh dan masa tertentu menggunakan kaedah (); 4. Gunakan kaedah tambah/tolak untuk meningkatkan dan mengurangkan masa; 5. Gunakan zoneddatetime dan zonid untuk memproses zon waktu; 6. Format dan parse date string melalui DateTimeFormatter; 7. Gunakan segera untuk bersesuaian dengan jenis tarikh lama apabila perlu; pemprosesan tarikh di java moden harus memberi keutamaan untuk menggunakan java.timeapi, yang memberikan jelas, tidak berubah dan linear

Pra-formancetartuptimemoryusage, quarkusandmicronautleadduetocompile-timeprocessingandgraalvsupport, withquarkusoftenperforminglightbetterine serverless scenarios.tyvelopecosyste,

NetworkPortsandFireWallSworkTogethertoenableCommunicationWileensuringsecurity.1.networkportsarevirtualendpointsNumbered0-655 35, Withwell-KnownportsLike80 (http), 443 (https), 22 (ssh), dan25 (smtp) identitispecificservices.2.portsoperateovertcp (boleh dipercayai, c

Koleksi Sampah Java (GC) adalah mekanisme yang secara automatik menguruskan ingatan, yang mengurangkan risiko kebocoran ingatan dengan menuntut semula objek yang tidak dapat dicapai. 1.GC menghakimi kebolehcapaian objek dari objek akar (seperti pembolehubah stack, benang aktif, medan statik, dan lain -lain), dan objek yang tidak dapat dicapai ditandakan sebagai sampah. 2. Berdasarkan algoritma penandaan tanda, tandakan semua objek yang dapat dicapai dan objek yang tidak ditandai. 3. Mengamalkan strategi pengumpulan generasi: Generasi Baru (Eden, S0, S1) sering melaksanakan MinorGC; Orang tua melakukan kurang tetapi mengambil masa lebih lama untuk melakukan MajorGC; Metaspace Stores Metadata kelas. 4. JVM menyediakan pelbagai peranti GC: SerialGC sesuai untuk aplikasi kecil; ParallelGC meningkatkan throughput; CMS mengurangkan

GradleisthebetterChoiceFormostNewProjectSduetoitSsuperiorflexibility, Prestasi, danModernToolingSupport.1.Gradle'sGroovy/KOT lindslismoreconciseandexpressivethanmaven'sverbosexml.2.GradleOutPerformsMaveninBuildSpeedWithIncrementalcompilation, BuildCac

Defer digunakan untuk melaksanakan operasi tertentu sebelum fungsi pulangan, seperti sumber pembersihan; Parameter dinilai dengan serta-merta apabila menangguhkan, dan fungsi-fungsi dilaksanakan mengikut urutan terakhir (LIFO); 1. Pelbagai penahanan dilaksanakan dalam urutan terbalik pengisytiharan; 2. Biasanya digunakan untuk pembersihan yang selamat seperti penutupan fail; 3. Nilai pulangan yang dinamakan boleh diubah suai; 4. Ia akan dilaksanakan walaupun panik berlaku, sesuai untuk pemulihan; 5. Elakkan penyalahgunaan menangguhkan gelung untuk mengelakkan kebocoran sumber; Penggunaan yang betul boleh meningkatkan keselamatan kod dan kebolehbacaan.

Memilih jenis htmlinput yang betul dapat meningkatkan ketepatan data, meningkatkan pengalaman pengguna, dan meningkatkan kebolehgunaan. 1. Pilih jenis input yang sepadan mengikut jenis data, seperti teks, e -mel, tel, nombor dan tarikh, yang secara automatik boleh menyemak dan menyesuaikan diri dengan papan kekunci; 2. Gunakan HTML5 untuk menambah jenis baru seperti URL, Warna, Julat dan Carian, yang dapat memberikan kaedah interaksi yang lebih intuitif; 3. Gunakan pemegang tempat dan sifat -sifat yang diperlukan untuk meningkatkan kecekapan dan ketepatan pengisian bentuk, tetapi harus diperhatikan bahawa pemegang tempat tidak dapat menggantikan label.
