溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Java多線程怎么設(shè)置優(yōu)先級(jí)

發(fā)布時(shí)間:2022-03-10 14:28:15 來源:億速云 閱讀:344 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“Java多線程怎么設(shè)置優(yōu)先級(jí)”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

    舉例說明:

    我們知道飛機(jī)在天上飛行是有固定的航線(可以理解成線程),每個(gè)機(jī)場(chǎng)都有最大的運(yùn)行負(fù)載能力,當(dāng)運(yùn)行情況超過了負(fù)載能力的時(shí)候,這就需要塔臺(tái)調(diào)度參與,會(huì)根據(jù)每架飛機(jī)的優(yōu)先級(jí)排序。當(dāng)在航線的時(shí)候,如果出現(xiàn)緊急情況,會(huì)讓其他飛機(jī)避讓,讓這架飛機(jī)優(yōu)先級(jí)提高,先降落。這就是調(diào)度,計(jì)算機(jī)程序線程運(yùn)行也是這樣的。

    1、線程的調(diào)度:

    在Java多線程中,主要可以通過下面四個(gè)方法來分配CPU的使用權(quán):

    • 設(shè)置優(yōu)先級(jí)(Priority) 設(shè)置線程的優(yōu)先級(jí),值是1-10

    • 休眠(sleep) 單位毫秒,讓本線程屬于阻塞狀態(tài),CPU會(huì)執(zhí)行其他線程

    • 強(qiáng)制運(yùn)行(join) 讓這個(gè)線程強(qiáng)制獲取CPU資源來運(yùn)行

    • 禮讓(yield) 暫停正在執(zhí)行的線程,讓其他線程先執(zhí)行,執(zhí)行完了在接著執(zhí)行

    1、設(shè)置優(yōu)先級(jí)(Priority):

    有兩個(gè)線程,分別設(shè)置最大優(yōu)先級(jí)和最小優(yōu)先級(jí):

    public class MyThread implements Runnable{
    
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+"正在運(yùn)行:"+i);
            }
        }
    
        public static void main(String[] args) {
            Thread t1 = new Thread(new MyThread(),"線程A:");
            Thread t2 = new Thread(new MyThread(),"線程B***:");
    
            //設(shè)置優(yōu)先級(jí): 最高為10  最低為1
            t1.setPriority(Thread.MAX_PRIORITY);
            t2.setPriority(Thread.MIN_PRIORITY);
    
            //顯示線程優(yōu)先級(jí):
            System.out.println("線程A的優(yōu)先級(jí)是:"+t1.getPriority());
            System.out.println("線程B的優(yōu)先級(jí)是:"+t2.getPriority());
    
            t1.start();
            t2.start();
        }
    }

    結(jié)果:

    Java多線程怎么設(shè)置優(yōu)先級(jí)

    2、休眠(sleep)

    Thread.sleep();--------單位是毫秒,讓本線程屬于阻塞狀態(tài),CPU會(huì)執(zhí)行其他線程:

    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("主線程執(zhí)行了:"+i+"s");
                try{
                    //讓線程休眠,進(jìn)入阻塞狀態(tài)
                    Thread.sleep(1000); //休眠時(shí)間為1000毫秒
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    結(jié)果:

    Java多線程怎么設(shè)置優(yōu)先級(jí)

    3、強(qiáng)制運(yùn)行(join)

    顧名思義,就是讓某個(gè)線程強(qiáng)制進(jìn)入執(zhí)行:

    子線程:

    public class MyThread {
    }

    測(cè)試類:

    public class Test {
        public static void main(String[] args) throws InterruptedException {
    
            Thread t1=  new Thread(new MyThread(),"我是子線程");
            t1.start();
            //當(dāng)主線程執(zhí)行任務(wù)1-10時(shí),如果執(zhí)行到5就讓子線程t1強(qiáng)制進(jìn)來執(zhí)行,直到執(zhí)行完了才讓主線程繼續(xù)執(zhí)行任務(wù)
            for (int i = 0; i < 6; i++) {
                if (i==2){
                    t1.join();
                }
                System.out.println(Thread.currentThread().getName()+"正在運(yùn)行:"+i);
            }
        }
    }

    結(jié)果:

    Java多線程怎么設(shè)置優(yōu)先級(jí)

    4、禮讓(yield)

    暫停正在執(zhí)行的線程,讓其他線程先執(zhí)行,執(zhí)行完了在接著執(zhí)行:

    public class MyThread implements Runnable{
    
        //線程禮讓,讓本線線程阻塞,其他線程先執(zhí)行
        //這里就是A線程運(yùn)行二次后,禮讓,讓B 線程先執(zhí)行
        //也是理論上的,就是不管怎么樣第二次后面肯定讓B先執(zhí)行,但是后面就隨機(jī)了
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+"正在運(yùn)行:"+i);
                if(i == 2){
                    Thread.yield();
                }
            }
        }
    }

    測(cè)試類:

    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();
        }
    }

    結(jié)果:

    Java多線程怎么設(shè)置優(yōu)先級(jí)

    2、定時(shí)器線程:

    定時(shí)器就是可以設(shè)置某個(gè)時(shí)間點(diǎn)來執(zhí)行某個(gè)事件,比如系統(tǒng)每周刪除依次日志文件,或者在指定的日期關(guān)閉系統(tǒng),定時(shí)器本身就是一個(gè)線程任務(wù)來在指定的時(shí)候執(zhí)行該任務(wù)。定時(shí)器是繼承TimerTask來重寫run方法,專門處理定時(shí)任務(wù)。

    演示Demo:

    public class MyThread extends TimerTask {
    
        @Override
        public void run() {
            //把任務(wù)定義在run方法中
            showMyself();
        }
    
        public void showMyself(){
            System.out.println("被Run方法執(zhí)行的");
        }
    }

    測(cè)試類:

    public class Test {
        public static void main(String[] args) {
    
            Timer timer = new Timer();
    
            //設(shè)置5秒后執(zhí)行這個(gè)任務(wù),并且每1秒重復(fù)執(zhí)行這個(gè)任務(wù)
    
            timer.schedule(new MyThread(),5000,1000);
    
        }
    }

    結(jié)果:

    Java多線程怎么設(shè)置優(yōu)先級(jí)

    3、線程的同步:

    首先我們先看一個(gè)demo:

    創(chuàng)建了兩個(gè)線程對(duì)象,一個(gè)線程A任務(wù)用于執(zhí)行print1,另一個(gè)線程B任務(wù)用于執(zhí)行print2:

    public void print1(){
            System.out.print("中");
            System.out.println("國");
        }
    
        public void print2(){
            System.out.print("浙");
            System.out.println("江");
        }
    }

    測(cè)試類:

    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();
        }
    }

    這個(gè)程序就是當(dāng)線程A執(zhí)行的時(shí)候,輸出中國,當(dāng)B執(zhí)行的時(shí)候,輸出浙江,理論上是沒有任何問題,但是我們看一下結(jié)果:

    Java多線程怎么設(shè)置優(yōu)先級(jí)

    我們發(fā)現(xiàn)出問題了,其實(shí)這就是非線程同步(異步):

    • 同步:提交請(qǐng)求->等待服務(wù)器處理->處理完返回 這個(gè)期間客戶端瀏覽器不能干任何事

    • 異步:請(qǐng)求通過事件觸發(fā)->服務(wù)器處理(這是瀏覽器仍然可以作其他事情)->處理完畢

    其實(shí)非線程同步在有些系統(tǒng)是很危險(xiǎn)的問題,比如12306,如果使用非線程同步,那么后果可想而知,那么該如何同步呢? 這里介紹一個(gè)常用的方法,就是上鎖:

    如果兩端代碼(兩個(gè)線程任務(wù))是同步的,那么CPU同一時(shí)間只能執(zhí)行一個(gè)任務(wù),相當(dāng)于給該線程上了一把鎖, 在該線程沒有執(zhí)行完這段代碼或者任務(wù)的時(shí)候,其他線程是不能占用CPU資源執(zhí)行任務(wù)的。直到執(zhí)行完了該線 程的代碼,其他線程才可以執(zhí)行。

    更好的理解(舉例):

    你去公共廁所上廁所(大的),當(dāng)你進(jìn)去后,需要把門關(guān)上并鎖著,這就是上鎖,為了保證你正常的結(jié)束(保證線程正常運(yùn)行完),這期間其他人是不能進(jìn)來的。

    Synchronized 鎖:

    兩個(gè)線程任務(wù)使用同一個(gè)對(duì)象為鎖,那么兩個(gè)線程方法是同步的 我們把上面的方法上個(gè)鎖:

    class Demo {
    }
    
    public class Printer {
    
       //創(chuàng)建任意一個(gè)對(duì)象,只要是對(duì)象相同就是鎖相同,就是同步的!
        Demo d = new Demo();  
    
        public void print1(){
        	//當(dāng)進(jìn)入print1這個(gè)方法時(shí),synchronized就給這個(gè)方法上了一個(gè)鎖
            synchronized (d){     
                System.out.print("中");
                System.out.println("國");
            }
        }
    
        public void print2(){
            //當(dāng)進(jìn)入print2這個(gè)方法時(shí),synchronized也給這個(gè)方法上了一個(gè)鎖
            synchronized (d){
                System.out.print("浙");
                System.out.println("江");
            }
        }
    
    }

    這樣輸出后就不會(huì)出現(xiàn)上面的那個(gè)問題,這里就不發(fā)結(jié)果截圖啦。大家可以自己試一試,看看是否解決了這個(gè)問題~

    我們還可以把鎖直接定義在方法上,比如這樣子:

    public static synchronized void print1(){
                System.out.print("中");
                System.out.println("國");
        }

    如果是靜態(tài)方法,上鎖的方式是通過.class字節(jié)碼對(duì)象:

    public static void print1() {
            synchronized (Printer.class) {
                System.out.print("中");
                System.out.println("國");
            }
        }

    Java多線程怎么設(shè)置優(yōu)先級(jí)

    “Java多線程怎么設(shè)置優(yōu)先級(jí)”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI