您好,登錄后才能下訂單哦!
本篇內容介紹了“Java多線程怎么設置優先級”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
舉例說明:
我們知道飛機在天上飛行是有固定的航線(可以理解成線程),每個機場都有最大的運行負載能力,當運行情況超過了負載能力的時候,這就需要塔臺調度參與,會根據每架飛機的優先級排序。當在航線的時候,如果出現緊急情況,會讓其他飛機避讓,讓這架飛機優先級提高,先降落。這就是調度,計算機程序線程運行也是這樣的。
在Java多線程中,主要可以通過下面四個方法來分配CPU的使用權:
設置優先級(Priority) 設置線程的優先級,值是1-10
休眠(sleep) 單位毫秒,讓本線程屬于阻塞狀態,CPU會執行其他線程
強制運行(join) 讓這個線程強制獲取CPU資源來運行
禮讓(yield) 暫停正在執行的線程,讓其他線程先執行,執行完了在接著執行
有兩個線程,分別設置最大優先級和最小優先級:
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多線程怎么設置優先級”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。