<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
舉例說明:
我們知道飛機在天上飛行是有固定的航線(可以理解成執行緒),每個機場都有最大的執行負載能力,當執行情況超過了負載能力的時候,這就需要塔臺排程參與,會根據每架飛機的優先順序排序。當在航線的時候,如果出現緊急情況,會讓其他飛機避讓,讓這架飛機優先順序提高,先降落。這就是排程,計算機程式執行緒執行也是這樣的。
在Java多執行緒中,主要可以通過下面四個方法來分配CPU的使用權:
有兩個執行緒,分別設定最大優先順序和最小優先順序:
public class MyThread implements Runnable{ @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName()+"正在執行:"+i); } } public static void main(String[] args) { Thread t1 = new Thread(new MyThread(),"執行緒A:"); Thread t2 = new Thread(new MyThread(),"執行緒B***:"); //設定優先順序: 最高為10 最低為1 t1.setPriority(Thread.MAX_PRIORITY); t2.setPriority(Thread.MIN_PRIORITY); //顯示執行緒優先順序: System.out.println("執行緒A的優先順序是:"+t1.getPriority()); System.out.println("執行緒B的優先順序是:"+t2.getPriority()); t1.start(); t2.start(); } }
結果:
Thread.sleep();--------單位是毫秒,讓本執行緒屬於阻塞狀態,CPU會執行其他執行緒:
public class ThreadSleep { public static void main(String[] args) { sleepTime(5); } private static void sleepTime(int time) { for (int i = 0; i < 5; i++) { System.out.println("主執行緒執行了:"+i+"s"); try{ //讓執行緒休眠,進入阻塞狀態 Thread.sleep(1000); //休眠時間為1000毫秒 } catch (InterruptedException e) { e.printStackTrace(); } } } }
結果:
顧名思義,就是讓某個執行緒強制進入執行:
子執行緒:
public class MyThread { }
測試類:
public class Test { public static void main(String[] args) throws InterruptedException { Thread t1= new Thread(new MyThread(),"我是子執行緒"); t1.start(); //當主執行緒執行任務1-10時,如果執行到5就讓子執行緒t1強制進來執行,直到執行完了才讓主執行緒繼續執行任務 for (int i = 0; i < 6; i++) { if (i==2){ t1.join(); } System.out.println(Thread.currentThread().getName()+"正在執行:"+i); } } }
結果:
暫停正在執行的執行緒,讓其他執行緒先執行,執行完了在接著執行:
public class MyThread implements Runnable{ //執行緒禮讓,讓本線執行緒阻塞,其他執行緒先執行 //這裡就是A執行緒執行二次後,禮讓,讓B 執行緒先執行 //也是理論上的,就是不管怎麼樣第二次後面肯定讓B先執行,但是後面就隨機了 @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName()+"正在執行:"+i); if(i == 2){ Thread.yield(); } } } }
測試類:
public class Test { public static void main(String[] args) { Thread t1 = new Thread(new MyThread(),"執行緒A:"); Thread t2 = new Thread(new MyThread(),"----執行緒B"); t1.start(); t2.start(); } }
結果:
定時器就是可以設定某個時間點來執行某個事件,比如系統每週刪除依次紀錄檔檔案,或者在指定的日期關閉系統,定時器本身就是一個執行緒任務來在指定的時候執行該任務。定時器是繼承TimerTask來重寫run方法,專門處理定時任務。
演示Demo:
public class MyThread extends TimerTask { @Override public void run() { //把任務定義在run方法中 showMyself(); } public void showMyself(){ System.out.println("被Run方法執行的"); } }
測試類:
public class Test { public static void main(String[] args) { Timer timer = new Timer(); //設定5秒後執行這個任務,並且每1秒重複執行這個任務 timer.schedule(new MyThread(),5000,1000); } }
結果:
首先我們先看一個demo:
建立了兩個執行緒物件,一個執行緒A任務用於執行print1,另一個執行緒B任務用於執行print2:
public void print1(){ System.out.print("中"); System.out.println("國"); } public void print2(){ System.out.print("浙"); System.out.println("江"); } }
測試類:
public class Test { public static void main(String[] args) { Printer p = new Printer(); //A: new Thread(new Runnable() { @Override public void run() { while(true){ p.print1(); } } },"執行緒A:").start(); //B: new Thread("執行緒B:"){ @Override public void run(){ while (true){ p.print2(); } } }.start(); } }
這個程式就是當執行緒A執行的時候,輸出中國,當B執行的時候,輸出浙江,理論上是沒有任何問題,但是我們看一下結果:
我們發現出問題了,其實這就是非執行緒同步(非同步):
其實非執行緒同步在有些系統是很危險的問題,比如12306,如果使用非執行緒同步,那麼後果可想而知,那麼該如何同步呢? 這裡介紹一個常用的方法,就是上鎖:
如果兩端程式碼(兩個執行緒任務)是同步的,那麼CPU同一時間只能執行一個任務,相當於給該執行緒上了一把鎖, 在該執行緒沒有執行完這段程式碼或者任務的時候,其他執行緒是不能佔用CPU資源執行任務的。直到執行完了該線 程的程式碼,其他執行緒才可以執行。
更好的理解(舉例):
你去公共廁所上廁所(大的),當你進去後,需要把門關上並鎖著,這就是上鎖,為了保證你正常的結束(保證執行緒正常執行完),這期間其他人是不能進來的。
Synchronized 鎖:
兩個執行緒任務使用同一個物件為鎖,那麼兩個執行緒方法是同步的 我們把上面的方法上個鎖:
class Demo { } public class Printer { //建立任意一個物件,只要是物件相同就是鎖相同,就是同步的! Demo d = new Demo(); public void print1(){ //當進入print1這個方法時,synchronized就給這個方法上了一個鎖 synchronized (d){ System.out.print("中"); System.out.println("國"); } } public void print2(){ //當進入print2這個方法時,synchronized也給這個方法上了一個鎖 synchronized (d){ System.out.print("浙"); System.out.println("江"); } } }
這樣輸出後就不會出現上面的那個問題,這裡就不髮結果截圖啦。大家可以自己試一試,看看是否解決了這個問題~
我們還可以把鎖直接定義在方法上,比如這樣子:
public static synchronized void print1(){ System.out.print("中"); System.out.println("國"); }
如果是靜態方法,上鎖的方式是通過.class位元組碼物件:
public static void print1() { synchronized (Printer.class) { System.out.print("中"); System.out.println("國"); } }
小結: 這篇文章主要介紹了執行緒的排程(四種)、執行緒的定時以及執行緒的同步,內容也不少,多執行緒是Java的一個難點,也沒用一些華麗的圖片來演示,在學習過程中會比較枯燥,包括我自己也是。大家也可以看看視訊,加深理解和印象!
到此這篇關於Java十分鐘入門多執行緒中篇的文章就介紹到這了,更多相關Java 多執行緒內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45