木舟0基礎學習Java的第二十天(線程,實現,匿名有名,休眠,守護,加入,設計,計時器,通信)

多線程

并發執行的技術

并發和并行

并發:同一時間 有多個指令 在單個CPU上?交替執行

并行:同一時間 有多個指令 在多個CPU上 執行

進程和線程

進程:獨立運行 任何進程 都可以同其他進程一起?并發執行

線程:是進程中的單個順序控制流 是一條執行路徑 線程又分為單線程和多線程

單線程:

多線程:JVM是多線程 其實就是JVM的主線程和垃圾回收線程在工作 結果在切換著運行

多線程的運行方式:他們擁有相等的運行權限 但運行過程是誰先搶到CPU的運行權限那么誰就先運行

線程的五種狀態:新建,就緒,運行,堵塞,死亡

線程的實現:

方式一:繼承Thread類

建立一個類繼承Thread類 那么這類創建的對象可以并發的作為獨立線程運行

繼承的好處是可以使用父類中的方法 比較簡單

繼承的弊端是如果已經有父類了 就不可以再繼承了 一個子類只能繼承一個父類

public class Demo02 {public static void main(String[] args) {MyThread1 m1=new MyThread1();MyThread2 m2=new MyThread2();MyThread3 m3=new MyThread3();//普通方法/* m1.run();m2.run();m3.run();*///start開啟新線程 內部會根據cpu的分配自動執行runm1.start();m2.start();m3.start();//相當于跑步比賽的發令槍 啟動后主線程與其他線程都會等待搶到cpu的執行權//誰先搶到誰運行}
}
//建立一個類繼承Thread類 那么這類創建的對象可以并發的作為獨立線程運行
class MyThread1 extends Thread{public void run(){for (int i = 0; i <10000000 ; i++) {System.out.println("1號線程");}}
}
class MyThread2 extends Thread{public void run(){for (int i = 0; i <10000000 ; i++) {System.out.println("2號線程");}}
}
class MyThread3 extends Thread{public void run(){for (int i = 0; i <10000000 ; i++) {System.out.println("3號線程");}}
}

方式二:實現Runnable接口

建立一個類實現Runnable接口

接口的好處是就算實現了其他接口 也可以使用

接口的弊端 操作不便利 需要先獲取Thread線程對象

public class Demo03 {public static void main(String[] args) {My1 my1=new My1();Thread t1=new Thread(my1);My2 my2=new My2();Thread t2=new Thread(my2);t1.start();t2.start();}
}
//定義一個類 實現Runnable接口 重新run方法class My1 implements Runnable{@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("1號線程");}}
}class My2 implements Runnable{@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("2號線程");}}
}

start()方法把當前線程交給了底層的? ThreadGroup group[]數組管理

Jvm根據隨機分配的cpu執行權調用run()? 隨機分配的cpu執行權是相等概率的

匿名內部類實現線程

方式一:繼承Thread類

 public static void main(String[] args) {new Thread(){public void run(){for(int i=0;i<10000000;i++){new Student();System.out.println("線程1");}}}.start();new Thread(){public void run(){for(int i=0;i<10000000;i++){new Student();System.out.println("線程2");}}}.start();}

方式二:實現Runnable接口

  public static void main(String[] args) {new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("1號線程");}}}).start();new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("2號線程");}}}).start();}

有名內部類實現線程

 public static void main(String[] args) {Thread t1=new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("1號線程");}}});Thread t2=new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println("2號線程");}}});t1.start();t2.start();}

設置名字和獲取名字(getName()?setName())

可以在運行中獲取當前線程的對象Thread.currentThread()

public class Demo06 {public static void main(String[] args) {Thread t1=new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {//Thread.currentThread()獲取當前運行的線程對象//獲取名字getName()System.out.println(Thread.currentThread().getName());}}});Thread t2=new Thread(new Runnable() {@Overridepublic void run() {for (int i = 0; i <10000000 ; i++) {System.out.println(Thread.currentThread().getName());}}});//設置名字t1.setName("線程1");t1.start();t2.setName("線程2");t2.start();}
}
通過構造方法給線程取名
public class Demo06 {public static void main(String[] args){//通過構造方法給線程取名Thread t1=new Thread(new M1(),"my1");Thread t2=new Thread(new M2(),"my2");t1.start();t2.start();}
}
class M1 implements Runnable{@Overridepublic void run() {for (int i = 0; i <100000 ; i++) {System.out.println(Thread.currentThread().getName());}}
}
class M2 implements Runnable{@Overridepublic void run() {for (int i = 0; i <100000 ; i++) {System.out.println(Thread.currentThread().getName());}}
}

休眠

Thread.sleep(100);讓當前線程休眠100毫秒

class MM1 implements Runnable{@Overridepublic void run() {for (int i = 0; i <100000 ; i++) {System.out.println(Thread.currentThread().getName());try {//讓當前線程休眠100毫秒Thread.sleep(100);} catch (InterruptedException e) {throw new RuntimeException(e);}}}

守護線程

線程.setDaemon(true);

設置一個線程為守護線程 該線程不會單獨執行 當其他非守護線程都執行結束后 再自動退出

public class Demo08 {public static void main(String[] args) {M2Thread m2=new M2Thread();m2.setName("線程2");m2.start();M1Thread m1=new M1Thread();m1.setName("線程1");m1.start();//守護線程不會單獨執行Thread1 t=new Thread1();t.setName("守護線程");t.setDaemon(true);//設置true為守護線程 主線程結束 守護線程也結束t.start();}
}
class M1Thread extends Thread{public void run(){for (int i = 0; i <100 ; i++) {System.out.println(Thread.currentThread().getName());}}
}
class M2Thread extends Thread{public void run(){for (int i = 0; i <100 ; i++) {System.out.println(Thread.currentThread().getName());}}
}
class Thread1 extends Thread{public void run(){for (int i = 0; i <10000 ; i++) {System.out.println(Thread.currentThread().getName()+i);}}
}

加入線程

線程.join(可以限定時間 也可以不限定);

  public static void main(String[] args) {Thread t1=new Thread("女朋友的電話"){public void run(){for (int i = 0; i <100 ; i++) {System.out.println(Thread.currentThread().getName()+i);}}};Thread t2=new Thread("老板的電話"){public void run(){for (int i = 0; i <100 ; i++) {System.out.println(Thread.currentThread().getName()+i);if(i==50){try {//加入女朋友的線程 基本全面占有cpu執行權// t2線程要等待t1線程執行完畢后才可以繼續執行t1.join();//可以限定時間} catch (InterruptedException e) {throw new RuntimeException(e);}}}}};t1.start();t2.start();}

禮讓(了解)

Thread.yield();//讓出cpu的執行權給別的線程

設置優先級:(優先級1-10 默認為5)

線程.setPriority(10);

同步(同步鎖,同步代碼塊)

注意:開發中盡量不要嵌套同步代碼塊 可能會死鎖
關鍵字:synchronized(同步鎖使用的多)
public class Test {String s="123";//同步鎖 在方法中加synchronized關鍵字//public synchronized void show1(){} public synchronized void show1(){System.out.print("我");System.out.print("愛");System.out.print("學");System.out.print("習");System.out.println("-----------");}public void show2(){//同步代碼塊synchronized(s鎖對象){}//多個同步代碼塊如果使用相同的鎖對象 那么他們就是同步的synchronized(s){ System.out.print("想");System.out.print("睡");System.out.print("覺");System.out.println("===========");}}
}

線程安全

synchronized線程安全? 沒有synchronized線程不安全

Vector線程安全? ArrayList線程不安全

Stringbuffer安全? stringBuilder不安全

HashTable安全? HashMap不安全

設計模式

單例設計模式

public class Single {private Single(){//私有構造方法 不讓其他類new對象}static Single s=new Single();
}
    public static void main(String[] args) {Single s1=Single.s;Single s2=Single.s;System.out.println(s1==s2);//trueSingle s3=null;//對象可以被修改Single s4=Single.s;System.out.println(s3==s4);//false}
餓漢式(直接加載)

節約時間 浪費空間(例如:安卓手機應用可以在后臺運行)

一旦被加載進來 就創建好了對象 不管是否使用 都在內存中
public class Single1 {private Single1(){//私有構造方法 不讓其他類new對象}static Single1 s=new Single1();//餓漢式public static Single1 getInstance(){//一旦被加載進來 就創建好了對象 不管是否使用 都在內存中return s;}
}
public static void main(String[] args) {Single s1=Single.getInstance();Single s2=Single.getInstance();System.out.println(s1==s2);//true}
懶漢式(延遲加載)

節約空間 浪費時間(例如:蘋果手機應用不掛后臺)

什么時候用 什么時候才創建
public class Single2 {private Single2(){}public static Single2 s=null;//懶漢式public static Single2 Instance(){//需要的時候才創建對象if(s==null){s=new Single2();}return s;}
}

Runtime類單例(查API)

每個 Java 應用程序都有一個Runtime類實例 使應用程序能夠與其運行的環境相連接 可以通過 getRuntime方法獲取當前運行時。

應用程序不能創建自己的 Runtime類實例

 public static void main(String[] args) {Runtime r=Runtime.getRuntime();try {//r.exec("mspaint");//打開畫圖//r.exec("notepad");//打開記事本//r.exec("shutdown -s -t 6000");//6000秒后自動關機//r.exec("shurdown -a");//取消自動關機//r.exec("百度去");} catch (IOException e) {throw new RuntimeException(e);}}

Timer類(計時器)

用來定時執行程序的類
public class MyTask extends TimerTask {@Overridepublic void run() {System.out.println("起床了");}
}
 public static void main(String[] args) {//用來定時執行程序的類Timer t=new Timer();//5秒后執行任務t.schedule(new MyTask(),new Date(System.currentTimeMillis()+5000));//5秒后執行任務 每隔1秒重復執行t.schedule(new MyTask(),new Date(System.currentTimeMillis()+5000),1000);}

線程通信(等待,喚醒)

必須在同步代碼塊中 使用同步鎖對象調用(喚醒 等待 喚醒 等待)代碼交替運行

并發執行時 默認情況下 cpu的執行權 是隨機的 誰先搶到誰先執行

如果希望有規律的執行 就可以用線程通信

notify喚醒 wait等待

案例:兩個方法交替

public class TestThread2 {public synchronized void print(){System.out.print("我");System.out.print("愛");System.out.print("學");System.out.print("習");System.out.println("-----------");this.notify();//喚醒正在等待的線程try {this.wait();//讓當前線程等待 讓出cpu執行權 進入就緒狀態} catch (InterruptedException e) {throw new RuntimeException(e);}}public synchronized void show(){System.out.print("想");System.out.print("睡");System.out.print("覺");System.out.println("===========");this.notify();//喚醒正在等待的線程try {this.wait();//讓當前線程等待 讓出cpu執行權 進入就緒狀態} catch (InterruptedException e) {throw new RuntimeException(e);}}
}
 public static void main(String[] args) {TestThread2 tt2=new TestThread2();new Thread(){public void run(){while(true){ tt2.print();}}}.start();new Thread(){public void run(){while(true){ tt2.show();}}}.start();}

案例:三個和三個以上方法交替

public class TestThread3 {boolean b1=true;boolean b2=false;boolean b3=false;public synchronized void show1() {if (b3) {System.out.print("我");System.out.print("愛");System.out.print("學");System.out.print("習");System.out.println("-----------");}b1 = true;b3 = false;this.notifyAll();//喚醒所有正在等待的線程try {this.wait();//讓當前線程等待 讓出cpu執行權 進入就緒狀態} catch (InterruptedException e) {throw new RuntimeException(e);}}public synchronized void show2(){if(b1){System.out.print("想");System.out.print("睡");System.out.print("覺");System.out.println("===========");}b2=true;b1=false;this.notifyAll();//喚醒所有正在等待的線程try {this.wait();//讓當前線程等待 讓出cpu執行權 進入就緒狀態} catch (InterruptedException e) {throw new RuntimeException(e);}}public synchronized void show3(){if(b2){System.out.print("想");System.out.print("吃");System.out.print("飯");System.out.println("~~~~~~~~~~~");}b2=false;b3=true;this.notifyAll();//喚醒所有正在等待的線程try {this.wait();//讓當前線程等待 讓出cpu執行權 進入就緒狀態} catch (InterruptedException e) {throw new RuntimeException(e);}}
}
 public static void main(String[] args) {TestThread3 tt3=new TestThread3();new Thread(){public void run(){while(true){tt3.show1();}}}.start();new Thread(){public void run(){while(true){tt3.show2();}}}.start();new Thread(){public void run(){while(true){tt3.show3();}}}.start();}

wait和sleep區別

wait():釋放鎖 等待并釋放鎖讓別的線程運行

sleep():不釋放鎖 在指定的時間抱著鎖睡 時間一到馬上醒來

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

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

相關文章

【.NET全棧】ASP.NET開發Web應用——站點導航技術

文章目錄 前言一、站點地圖1、定義站點地圖文件2、使用SiteMapPath控件3、SiteMap類4、URL地址映射 二、TreeView控件1、使用TreeView控件2、以編程的方式添加節點3、使用TreeView控件導航4、綁定到XML文件5、按需加載節點6、帶復選框的TreeView控件 三、Menu控件1、使用Menu控…

Hutool-Guava

目錄 一、Guava 二、Hutool 三、區別與聯系 四、使用場景 五、Guava工具類 1.集合工具類 2.字符串工具類 3.并發工具類 六、Hutool 1.字符串工具類 2.文件工具類 Hutool 和 Guava 都是 Java 開發中非常實用的工具庫&#xff0c;它們提供了許多方便的工具類和方法&am…

字節抖音電商 后端開發崗位 一面

筆者整理答案&#xff0c;以供參考 自我介紹 項目&#xff08;20分鐘&#xff09; RocketMQ延時消息的底層實現 回答&#xff1a; 延時消息的實現主要依賴于RocketMQ中的定時任務機制。消息被發送到Broker時&#xff0c;會先存儲在一個特定的延時消息隊列中。Broker會定時掃…

c++ extern 關鍵字

C中的extern關鍵字和跨語言互操作 變量的聲明與定義 extern關鍵字用于聲明在另一個翻譯單元&#xff08;文件&#xff09;中定義的變量或函數。通過extern關鍵字&#xff0c;可以在多個文件中訪問全局變量或函數。 變量聲明示例 文件&#xff1a;main.cpp #include <io…

chatglm2-6b-prompt嘗試

參考https://cloud.tencent.com/developer/article/2426296 chatglm2-6b&#xff0c;通過prompt來實現zero-shot/fewshot的自然語言處理任務 import json import re import os from modelscope.utils.constant import Tasks from modelscope import Model from modelscope.pi…

再議擴散模型

目錄 一、基礎知識 1、數學期望 2、概率表示 3、KL散度 二、擴散過程 三、理想的去噪過程 四、真實的去噪過程 五、噪聲生成 導言 筆者早些時候曾粗略看過擴散模型的流程&#xff0c;但對于底層算法&#xff08;尤其是概率論方面&#xff09;&#xff0c;理解不夠透徹…

pytorch學習(五)tensorboard使用

1. 創建環境 首先創建一個環境: conda create -n pytorch conda activate pytorch 然后安裝tensorboard pip install tensorboard 安裝opencv pip install opencv-python 2. 簡單的案例 標量和圖像的顯示&#xff1a; 2.1標量實現的方法是add_scalar,第一個參數是給顯…

探索Puppeteer的強大功能:抓取隱藏內容

背景/引言 在現代網頁設計中&#xff0c;動態內容和隱藏元素的使用越來越普遍&#xff0c;這些內容往往只有在特定的用戶交互或條件下才會顯示出來。為了有效地獲取這些隱藏內容&#xff0c;傳統的靜態爬蟲技術往往力不從心。Puppeteer&#xff0c;作為一個強大的無頭瀏覽器工…

印尼語翻譯通:AI驅動的智能翻譯與語言學習助手

在這個多元文化交織的世界中&#xff0c;語言是連接我們的橋梁。印尼語翻譯通&#xff0c;一款專為打破語言障礙而生的智能翻譯軟件&#xff0c;讓您與印尼語的世界輕松接軌。無論是商務出差、學術研究&#xff0c;還是探索印尼豐富的文化遺產&#xff0c;印尼語翻譯通都是您的…

代碼隨想錄算法訓練營第三十六天|1049. 最后一塊石頭的重量 II 、 494. 目標和 、 474.一和零

1049. 最后一塊石頭的重量 II 分成兩堆石頭&#xff0c;一堆石頭的總重量是dp[target]&#xff0c;另一堆就是sum - dp[target]。 在計算target的時候&#xff0c;target sum / 2 因為是向下取整&#xff0c;所以sum - dp[target] 一定是大于等于dp[target]的。 那么相撞之…

.NET C# 使用 iText 生成PDF

.NET C# 使用 iText 生成PDF 文章目錄 .NET C# 使用 iText 生成PDF1 安裝 iText 7 庫&#xff1a;2 變量定義3 創建一個PDF4 段落5 旋轉文本6 代碼塊7 外部鏈接8 內部鏈接9 表格10 注釋11 線條12 二維碼13 嵌入圖像14 列表15 設置背景16 頁眉17 頁腳18 事件19 水印20 分欄21 源…

老古董Lisp(1):粗魯先生Lisp再出發

粗魯先生Lisp再出發 開始的原因 目標和夢想是最近考慮的一個問題。什么是目標&#xff1f;什么是夢想&#xff1f;夢想可以激勵改變&#xff0c;目標才能實現改變。 開始這個部分的時候&#xff0c;我的夢想是什么&#xff1f;我的目標是什么&#xff1f;我想要什么&#xf…

libwebrtc.a+exosip連接fS 環境部署tips

//運行FS服務器 sudo ./freeswitch -nc -nonat //公網sudo ./freeswitch //運行客戶端 sudo ./fs_cli //加載模塊 load mod_av load mod_verto0.Invite交互過程 1.fs碼率設置 2.用戶密碼改動 3.數字簽名的摘要 4.FS收不到ACK 5.公網部署 6.查看frewswitch都占用哪些端口 7.日志…

Java(二十一)---棧的使用和模擬實現

文章目錄 前言1.什么是棧(Stack)?2. 棧的模擬實現3.stack的使用![在這里插入圖片描述](https://i-blog.csdnimg.cn/direct/80c82d22f3ee49cfaa2915d1c961573e.png)4.關于棧的oj題4.1.有效的括號4.2.逆波蘭表達式4.3.棧的壓入、彈出序列4.4.最小棧 前言 前面幾篇我們學習了順序…

Vue--Router(路由)

目錄 一 Router(路由) 1.作用 2.實現步驟 3.注意 一 Router(路由) 1.作用 Router又叫做路由&#xff0c;簡單來說&#xff0c;就是用來實現vue的頁面之間跳轉的。 我們都知道&#xff0c;使用vue必然會涉及到很多個組件&#xff0c;也就是頁面&#xff0c;而頁面之間肯定需…

RK3588讀取不到顯示器edid

問題描述 3588HDMIout接老的顯示器或者HDMI轉DVI接DVI顯示器顯示不了或者顯示內容是彩色條紋,但是這種顯示器測試過如果接筆記本或者主機是可以直接顯示的。這一類問題是HDMI下的i2c與顯示器通訊沒成功,讀取不到設備的edid。問題包括全志的H3 、AML的S905都有遇到 測試環境…

Qt-事件與信號

事件和信號的區別在于&#xff0c;事件通常是由窗口系統或應用程序產生的&#xff0c;信號則是Qt定義或用戶自定義的。Qt為界面組件定義的信號往往通常是對事件的封裝&#xff0c;如QPushButton的clicked()信號可以看做對QEvent::MouseButtonRelease類事件的封裝。 在使用界面組…

【QGroundControl二次開發】二.使用QT編譯QGC(Windows)

【QGroundControl二次開發】一.開發環境準備&#xff08;Windows&#xff09; 二. 使用QT編譯QGC&#xff08;Windows&#xff09; 2.1 打開QT Creator&#xff0c;選擇打開項目&#xff0c;打開之前下載的QGC項目源碼。 編譯器選擇Desktop Qt 6.6.3 MSVC2019 64bit。 點擊運…

vue3-tree-org實現帶照片的組織架構圖

官方文檔&#xff1a;vue3-tree-org 顯示照片需要注意的地方 使用步驟 下載 npm install vue3-tree-org --save 在main.js中引入 import "vue3-tree-org/lib/vue3-tree-org.css"; import vue3TreeOrg from vue3-tree-org;app.use(vue3TreeOrg) 實現代碼 <tem…

level 6 day2 網絡基礎2

1.socket&#xff08;三種套接字&#xff1a;認真看&#xff09; 套接字就是在這個應用空間和內核空間的一個接口&#xff0c;如下圖 原始套接字可以從應用層直接訪問到網絡層&#xff0c;跳過了傳輸層&#xff0c;比如在ubtan里面直接ping 一個ip地址,他沒有經過TCP或者UDP的數…