【線程創建】——三種方式?多線程案例練習

02 線程創建

Thread , Runnable , Callable

三種創建方式

Thread class - 繼承Thread類 (重點)

Runnable接口 - 實現Runnable接口 (重點)

Callable接口 - 實現Callable接口 (了解)

Thread 類實現

它繼承了老祖宗 Object
java.lang.Object
java.lang.Thread

它實現了 Runnable接口

線程是程序中執行的線程. Java虛擬機允許應用程序同時執行多個執行線程.

每個線程都有優先權. 就是你的優先權更高你先執行, 你的優先權低你就后執行, 還有守護線程, 和用戶線程, 這個地方先不聊, 本章主要講如何創建線程

創建一個新的線程有兩種方法, 一個是將一個類聲明為Thread的子類, 這個子類應該重新run類的方法Thread. 然后可以分配并啟動子類的實例. 例如, 計算大于規定值的素數的線程可以寫成如下:

  • 自定義線程類繼承**Thread類**
  • 重寫**run()**方法
  • 創建線程對象, 調用**start()**方法啟動線程
繼承Thread類實現

我們下面用代碼實現一下:

package com.jean.thread;//創建線程方式一: 繼承Thread類, 重寫run()方法, 調用start開啟線程
public class TestThread1 extends Thread {//    繼承完, 立即重寫run方法@Overridepublic void run() {
//        run方法線程體for (int i = 0; i < 20; i++) {System.out.println("我在看代碼----"+i);}}public static void main(String[] args) {
//        main線程, 主線程for (int i = 0; i < 20; i++) {System.out.println("我在學習多線程----"+i);}}
}

我們執行后, 控制臺加載完后就一瞬間輸出了20個我在學習多線程, 我們如果想把另一個線程開啟怎么開呢?

package com.jean.thread;//創建線程方式一: 繼承Thread類, 重寫run()方法, 調用start開啟線程
public class TestThread1 extends Thread {//    繼承完, 立即重寫run方法@Overridepublic void run() {
//        run方法線程體for (int i = 0; i < 20; i++) {System.out.println("我在看代碼----"+i);}}public static void main(String[] args) {
//        main線程, 主線程//        首先創建它的一個對象TestThread1 testThread1 = new TestThread1();
//        調用start方法, 開啟線程testThread1.start();for (int i = 0; i < 20; i++) {System.out.println("我在學習多線程----"+i);}}
}

在這里插入圖片描述

我們調用了start方法后, 控制臺明顯執行的先后順序就隨機了, 所以說

調用start()方法是同時來運行的, 交替執行

我們的多線程調用了一個start方法, 它直接走下來進了start方法, 他開辟了一條新的線程, 它去執行它的方法, 主線程依據去走主線程的

然后我們再改調用run()方法

package com.jean.thread;//創建線程方式一: 繼承Thread類, 重寫run()方法, 調用start開啟線程
public class TestThread1 extends Thread {//    繼承完, 立即重寫run方法@Overridepublic void run() {
//        run方法線程體for (int i = 0; i < 20; i++) {System.out.println("我在看代碼----"+i);}}public static void main(String[] args) {
//        main線程, 主線程//        首先創建它的一個對象TestThread1 testThread1 = new TestThread1();
//        調用run方法, 開啟線程testThread1.run();for (int i = 0; i < 20; i++) {System.out.println("我在學習多線程----"+i);}}
}

在這里插入圖片描述
使用run方法調用, 他先走run方法, 執行完了才去執行主路徑

總結:

線程開啟不一定立即執行, 由CPU調度安排

多線程網圖下載

案例: 下載圖片

使用多線程同時去下載幾個圖片

  1. 先引入一下jar包 Commons IO包.

可以直接去百度搜索Commons IO , 是Apache下的.

  • Commons IO是針對開發IO流功能的工具類庫.

  • FileUtils文件工具, 復制url到文件

Commons-io包的下載地址
在這里插入圖片描述
點擊圖中紅色圈起來的jar鏈接即可實現下載

創建lib文件, 把lib目錄添加為庫.

  1. 創建lib文件
  2. 點擊lib文件獲取焦點, 右鍵點擊
  3. 選擇添加為庫
  4. 添加為jar
    在這里插入圖片描述
    添加成功之后, 文件前會有一個箭頭

新建TestDownload文件

package com.jean.thread;import org.apache.commons.io.FileUtils;import java.io.File;
import java.io.IOException;
import java.net.URL;/*** @BelongsProject: Thread-class01* @BelongsPackage: com.jean.thread* @Author: Jean_z* @CreateTime: 2024-05-13  08:31* @Description: TODO: 練習Thread, 實現多線程同步下載圖片* @Version: 1.0*/
public class TestDownload implements Runnable{private String url; //網絡圖片地址private String name; //保存的文件名//    構造器public TestDownload(String url, String name) {this.url = url;this.name = name;}//    下載圖片線程的執行體@Overridepublic void run() {WebDownload webDownload = new WebDownload();webDownload.download(url,name);System.out.println("下載了文件名為:" + name);}//    啟動線程public static void main(String[] args) {TestDownload testDownload1 = new TestDownload("https://img-home.csdnimg.cn/images/20240511083237.png", "我是圖片的名字1");TestDownload testDownload2 = new TestDownload("https://img-home.csdnimg.cn/images/20240511083237.png", "我是圖片的名字2");TestDownload testDownload3 = new TestDownload("https://img-home.csdnimg.cn/images/20240511083237.png", "我是圖片的名字3");//        Thread類方法
//        testDownload1.start();
//        testDownload2.start();
//        testDownload3.start();//        Runnable接口方法new Thread(testDownload1).start();new Thread(testDownload2).start();new Thread(testDownload3).start();}
}// 下載器
class WebDownload {
//    下載方法public void download(String url,String name) {
//        FileUtils: 文件工具
//        copyURLToFile 拷貝url地址到一個文件try {FileUtils.copyURLToFile(new URL(url),new File(name));} catch (IOException e) {e.printStackTrace();System.out.println("IO異常, download 方法出問題了");}}
}

Runnable接口實現多線程.

跟推薦的一種實現多線程的方式: Runnable

創建線程方式2

  1. 實現Runnable接口,
  2. 重寫run方法, 執行線程需要丟入runnable接口實現類,調用start方法.
package com.jean.thread;/*** @BelongsProject: Thread-class01* @BelongsPackage: com.jean.thread* @Author: Jean_z* @CreateTime: 2024-05-13  09:38* @Description: TODO* @Version: 1.0*///創建線程方式2 : 實現Runnable接口, 重寫run方法, 執行線程需要丟入runnable接口實現類,調用start方法.
public class TestRunnable implements Runnable{//    繼承完, 立即重寫run方法@Overridepublic void run() {
//        run方法線程體for (int i = 0; i < 20; i++) {System.out.println("我在看代碼----"+i);}}public static void main(String[] args) {
//        main線程, 主線程
//        創建runnable接口的實現對象TestRunnable runnable = new TestRunnable();//        創建線程對象, 通過線程對象來開啟我們的線程, 代理
//        Thread thread = new Thread(runnable);
//        調用start方法, 開啟線程new Thread(runnable).start();for (int i = 0; i < 2000; i++) {System.out.println("我在學習多線程----"+i);}}
}

Callable 方式 實現多線程

第三種實現多線程的方式: Callable

我們基于多線程下載網絡圖片代碼, 修改.

  1. 實現Callable接口

  2. 重寫call方法 類型

  3. 創建執行事務

    ExecutorService executorService = Executors.newFixedThreadPool (3);

  4. 提交執行

  5. 獲取執行結果, boolean類型

  6. 關閉服務

之前是重寫run方法, 我們這里不一樣, 重寫的是call方法, 注意方法類型是布爾.

第三種方式, 了解即可 !

package com.jean.thread;import org.apache.commons.io.FileUtils;import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;/*** @BelongsProject: Thread-class01* @BelongsPackage: com.jean.thread* @Author: Jean_z* @CreateTime: 2024-05-13  08:31* @Description: TODO: 練習Thread, 實現多線程同步下載圖片* @Version: 1.0*/
public class TestCallable implements Callable<Boolean> {private String url; //網絡圖片地址private String name; //保存的文件名//    構造器public TestCallable(String url, String name) {this.url = url;this.name = name;}//    下載圖片線程的執行體@Overridepublic Boolean call() {WebDownload2 webDownload = new WebDownload2();webDownload.download(url,name);System.out.println("下載了文件名為:" + name);return true;}//    啟動線程public static void main(String[] args) throws ExecutionException, InterruptedException {TestCallable testCallable1= new TestCallable("https://img-home.csdnimg.cn/images/20240511083237.png", "我是圖片的名字1");TestCallable testCallable2= new TestCallable("https://img-home.csdnimg.cn/images/20240511083237.png", "我是圖片的名字2");TestCallable testCallable3= new TestCallable("https://img-home.csdnimg.cn/images/20240511083237.png", "我是圖片的名字3");//        Thread類方法
//        testDownload1.start();
//        testDownload2.start();
//        testDownload3.start();//        創建執行事務ExecutorService executorService = Executors.newFixedThreadPool(3);//        提交執行Future<Boolean> r1 = executorService.submit(testCallable1);Future<Boolean> r2 = executorService.submit(testCallable2);Future<Boolean> r3 = executorService.submit(testCallable3);//        獲取結果boolean rs1 = r1.get();boolean rs2 = r2.get();boolean rs3 = r3.get();System.out.println(rs1);System.out.println(rs2);System.out.println(rs3);//        關閉服務executorService.shutdownNow();}
}// 下載器
class WebDownload2 {
//    下載方法public void download(String url,String name) {
//        FileUtils: 文件工具
//        copyURLToFile 拷貝url地址到一個文件try {FileUtils.copyURLToFile(new URL(url),new File(name));} catch (IOException e) {e.printStackTrace();System.out.println("IO異常, download 方法出問題了");}}
}

多線程 “龜🐢” “兔🐇” 賽跑案例

案例需求:

  1. 首先先來個賽道距離, 然后要離重點越來越近
  2. 判斷比賽是否結束
  3. 打印出勝利者
  4. 龜兔賽跑開始
  5. 故事中是烏龜🐢速度慢但是依舊是烏龜贏的, 兔子🐇需要睡覺, 所以我們來模擬兔子睡覺💤
  6. 終于, 烏龜🐢贏得比賽.
sleep多線程的延時方法

Thread.sleep ( 5000 ) // 這里是毫秒

package com.jean.thread;/*** @BelongsProject: Thread-class01* @BelongsPackage: com.jean.thread* @Author: Jean_z* @CreateTime: 2024-05-13  10:21* @Description: TODO* @Version: 1.0*/
//模擬龜兔賽跑
public class TestRace implements Runnable{//    勝利者private static String winner;
//    private static String winner;@Overridepublic void run() {for (int i = 1; i <= 100; i++) {//            模擬兔子休息if (Thread.currentThread().getName().equals("兔子🐇")) {try {Thread.sleep(30);} catch (InterruptedException e) {e.printStackTrace();System.out.println("兔子🐇喝伏特加了, 無比清醒, 不想睡覺");}}//            模擬烏龜速度if (Thread.currentThread().getName().equals("烏龜🐢")) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}//            判斷比賽是否接結束boolean flag = gameOver(i);
//            比賽結束停止程序if (flag) {break;}System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步");}}//    判斷是否完成比賽private boolean gameOver(int steps) {
//        判斷是否有勝利者if (winner!=null) { //已經存在勝利者了return true;}{if (steps>=100){winner = Thread.currentThread().getName();System.out.println("最終勝利者 is "+winner);return true;}}return false;}//賽道public static void main(String[] args) {TestRace race = new TestRace();new Thread(race,"兔子🐇").start();new Thread(race,"烏龜🐢").start();}}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/11706.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/11706.shtml
英文地址,請注明出處:http://en.pswp.cn/web/11706.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

文本到語音的學習筆記:從Docker開始

1.docker 是什么意思&#xff1f; Docker 是一種開源的容器化平臺&#xff0c;它允許開發者將應用及其依賴打包到一個輕量級、可移植的容器中&#xff0c;然后可以在任何支持Docker的系統上運行這個應用&#xff0c;而不必擔心環境差異導致的問題。 以下是Docker的一些關鍵特…

原子操作std::atomic

std::atomic是 C11 標準庫提供的一個模板類&#xff0c;用于實現原子操作。原子操作是指不會被線程調度機制打斷的操作&#xff0c;即這種操作一旦開始&#xff0c;就一直運行到結束&#xff0c;中間不會有任何線程切換。在多線程編程中&#xff0c;原子操作對于確保數據的一致…

EasyExcel 導出,保留兩位小數并顯示 千分位

實體類 屬性類型為 BigDecimal 注解 NumberFormat("#,###.00") 試過了不頂用&#xff0c;原因不太清楚 值為 0.81 這種&#xff0c;導出后變為 .81 所以&#xff0c;換個思路&#xff0c;寫個轉換器&#xff0c;就是麻煩點 轉換器 BigDecimalConvert import cn.h…

【go項目01_學習記錄11】

操作數據庫 1 文章列表2 刪除文章 1 文章列表 &#xff08;1&#xff09;先保證文章已經有多篇&#xff0c;可以直接在數據庫中添加&#xff0c;或者訪問鏈接: localhost:3000/articles/create&#xff0c;增加幾篇文章。 &#xff08;2&#xff09;之前設置好了articles.ind…

【Web后端】監聽器Listener

1、簡介 用來監聽Servlet組件對象狀態發生變化的組件可以監聽的源包括:ServetRequest、HttpSession、ServletContext當監聽到事件源狀態發生變化時&#xff0c;會有對應的響應行為 2、使用方法 在web.xml文件中配置 <listener> <listener-class>com.coder.util.…

【DevOps】詳解 Linux 用戶和權限管理:添加用戶、分組及文件權限設置

目錄 1. 用戶管理 用戶分類 用戶相關文件 常用命令 2. 組管理 組相關文件 常用命令 3. 權限管理 文件權限 權限表示 修改權限 修改所有者和所屬組 特殊權限 4. 示例 命令的詳細解釋 權限解釋 示例&#xff1a;文件權限 -rw-r--r-- 的含義 在 Linux 中&#xf…

棧隊列經典OJ題(詳細過程)

1. 有效的括號 - 力扣&#xff08;LeetCode&#xff09; 第一題判斷有效的括號&#xff0c;這道題我們會用到棧的知識&#xff0c;棧是后進先出的&#xff0c;可以根據這個來解這道題&#xff0c;先看一下題目和示例。 1.1整體思路 我們通過示例可以看出括號匹配就返回true&am…

【JAVA】BOSS系統發版藝術:構建高效、優雅的微服務部署策略

在現代軟件開發領域&#xff0c;微服務架構與容器化部署已迅速成為行業新趨勢。微服務架構通過將應用拆分成多個小型、自治的服務單元&#xff0c;每個服務承擔某項特定的業務功能。而容器化部署則以其輕量級和高度可移植的特性&#xff0c;為這些微服務的有效打包、分發和運行…

機器學習 - 不同分類模型的比較

一、模型訓練 本案例中&#xff0c;我們將通過四種不同的模型來預測泰坦尼克號乘客的生存情況。 一下是訓練的具體步驟。 加載數據 從seaborn庫中加載目標數據。該數據集包括多個特征&#xff0c;如 PassengerId, Pclass, Name, Sex, Age, SibSp, Parch, Ticket, Fare, Cabi…

科技查新中的工法查新點如何確立與提煉?案例講解!

按《工程建設工法管理辦法》( 建 質&#xff3b;2014&#xff3d;103 號) &#xff0c;工法&#xff0c;是指以工程為對象&#xff0c;以工藝為核心&#xff0c;運用系 統工程原理&#xff0c;把先進技術和科學管理結合起來&#xff0c;經過一定工程實踐形成的綜合配套的施工方…

探索美國動態IP池:技術賦能下的網絡安全新篇章

在數字化飛速發展的今天&#xff0c;網絡安全成為了各行各業關注的焦點。特別是在跨國業務中&#xff0c;如何保障數據的安全傳輸和合規性成為了企業面臨的重要挑戰。美國動態IP池作為一種新興的網絡技術&#xff0c;正逐漸走進人們的視野&#xff0c;為網絡安全提供新的解決方…

黑馬甄選離線數倉項目day02(數據采集)

datax介紹 官網&#xff1a; https://github.com/alibaba/DataX/blob/master/introduction.md DataX 是阿里云 DataWorks數據集成 的開源版本&#xff0c;在阿里巴巴集團內被廣泛使用的離線數據同步工具/平臺。 DataX 實現了包括 MySQL、Oracle、OceanBase、SqlServer、Postgre…

Java中List接口中方法的使用(初學者指南)

Java中List接口中方法的使用&#xff08;初學者指南&#xff09; 在Java中&#xff0c;List接口是Collection接口的子接口&#xff0c;它表示一個有序的集合&#xff0c;其中的元素都可以重復。List接口提供了許多額外的方法&#xff0c;用于對元素進行插入、刪除、查詢等操作…

計算機Java項目|Springboot學生讀書筆記共享

作者主頁&#xff1a;編程指南針 作者簡介&#xff1a;Java領域優質創作者、CSDN博客專家 、CSDN內容合伙人、掘金特邀作者、阿里云博客專家、51CTO特邀作者、多年架構師設計經驗、騰訊課堂常駐講師 主要內容&#xff1a;Java項目、Python項目、前端項目、人工智能與大數據、簡…

C++通過json文件配置參數

一、安裝nlohmann json nlohmann json&#xff1a;安裝_nlohmann安裝-CSDN博客 依次執行下面指令&#xff1a; git clone https://gitee.com/cuihongxi/mov_from_github.gitcd json-developmkdir buildcd buildcmake ..makesudo make install 二、安裝完成后使用 #include…

華為設備display查看命令

display version //查看版本信息 display current-configuration //查看配置詳情 display this //查看當前視圖有效配置 display ip routing-table //查看路由表 display ip routing-table 192.168.3.1 //查看去往3.1的路由 display ip interface brief //查看接口下ip信息 dis…

想跨境出海?云手機提供了一種可能性

全球化時代&#xff0c;越來越多的中國電商開始將目光投向了海外市場。這并不是偶然&#xff0c;而是他們在長期的市場運營中&#xff0c;看到了出海的必要性和潛在的機會。 中國的電商市場無疑是全球最大也最發達的之一。然而&#xff0c;隨著市場的不斷發展和競爭的日益加劇…

visual studio2022 JNI極簡開發流程

文章目錄 1 創建java類2 生成JNI頭文件3 使用visual studio2022創建DLL項目3.1 選擇模板中&#xff08;Windows桌面向導&#xff09;3.2 為項目命名3.3 選擇應用程序類型為動態鏈接庫3.4 項目概覽 4 導入需要的頭文件4.1 導入需要的頭文件4.2 修改頭文件 5 編寫C實現6 生成dll文…

服務器3389端口,服務器3389端口風險提示的應對措施

3389端口是Windows操作系統中遠程桌面協議&#xff08;RDP&#xff09;的默認端口。一旦該端口被惡意攻擊者利用&#xff0c;可能會導致未經授權的遠程訪問和數據泄露等嚴重安全問題。 針對此風險&#xff0c;強烈建議您采取以下措施&#xff1a; 1. 修改默認端口&#xff1a;…

Java面試之抽象類和接口

Java的一個重要特性就是抽象&#xff0c;抽象是指將具體的事物抽象成更一般化、更抽象化的概念或模型。在Java中&#xff0c;抽象可以通過抽象類和接口來實現&#xff0c;它們讓你能夠定義一些方法但不提供具體實現&#xff0c;從而讓子類去實現具體細節。 一、抽象類&#xf…