欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java Thread多線程開(kāi)發(fā)中Object類詳細(xì)講解

 更新時(shí)間:2023年03月01日 09:55:28   作者:健鑫.  
這篇文章主要介紹了Java Thread多線程開(kāi)發(fā)中Object類,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧

方法概覽

Thread

wait  notify notifyAll方法詳解

作用

阻塞階段

使用了wait方法之后,線程就會(huì)進(jìn)入阻塞階段,只有發(fā)生以下四種情況中的其中一個(gè),線程才會(huì)被喚醒

  • 另一個(gè)線程調(diào)用了這個(gè)線程的notify方法,剛好喚醒的是本線程
  • 另一個(gè)線程調(diào)用了這個(gè)對(duì)象的notifyAll方法
  • 過(guò)了wait規(guī)定的超時(shí)時(shí)間
  • 線程調(diào)用了interrupt

喚醒階段

notify會(huì)喚醒單個(gè)處于阻塞狀態(tài)的線程,喚醒的線程是隨機(jī)的

notify和wait都需要寫(xiě)在synchronized代碼塊里,不然會(huì)拋出異常

notifyAll會(huì)喚醒所有等待的線程

遇到中斷

執(zhí)行wait方法之后,被中斷,會(huì)拋出InterruptedException這個(gè)異常

代碼展示

  • 展示wait和notify的基本用法
  • 該代碼執(zhí)行wait方法之后會(huì)釋放鎖,然后thread2執(zhí)行notify方法
  • notify方法執(zhí)行完畢之后,并沒(méi)有立即釋放鎖,而是接著執(zhí)行之后的代碼,也就是打印“Thread2調(diào)用notify”這句話
  • thread2執(zhí)行完畢之后,會(huì)進(jìn)行釋放鎖,thread1才會(huì)繼續(xù)執(zhí)行
  • 在此期間,thread1雖然被喚醒,但是一直在等待thread2同步代碼塊里面的代碼執(zhí)行完畢
public class Wait {
    public static void main(String[] args) throws InterruptedException {
        Thread1 thread1 = new Thread1();
        Thread2 thread2 = new Thread2();
        thread1.start();
        Thread.sleep(200);
        thread2.start();
    }
    public static Object object = new Object();
    static class Thread1 extends Thread {
        @Override
        public void run() {
            synchronized (object) {
                System.out.println("Thread1執(zhí)行");
                try {
                    object.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("Thread1獲取鎖");
            }
        }
    }
    static class Thread2 extends Thread {
        @Override
        public void run() {
            synchronized (object) {
                object.notify();
                System.out.println("Thread2調(diào)用notify");
            }
        }
    }
}
/*
Thread1執(zhí)行
Thread2調(diào)用notify
Thread1獲取鎖
* */
  • notify和notifyAll的展示
  • 第一個(gè)輸出:threadc調(diào)用notifyAll
  • 第二個(gè)輸出:threadc調(diào)用notify
  • 調(diào)用notify的時(shí)候,程序并沒(méi)有結(jié)束,threadb陷入等待
public class notifyOrAll implements Runnable{
    private static final Object a = new Object();
    public static void main(String[] args) throws InterruptedException {
        Runnable r = new notifyOrAll();
        Thread threada = new Thread(r);
        Thread threadb = new Thread(r);
        Thread threadc = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (a) {
//                    a.notifyAll();
                    a.notify();
                    System.out.println(Thread.currentThread().getName() + "notify");
                }
            }
        });
        threada.start();
        Thread.sleep(200);
        threadb.start();
        Thread.sleep(200);
        threadc.start();
    }
    @Override
    public void run() {
        synchronized (a) {
            System.out.println(Thread.currentThread().getName() + "得到鎖");
            try {
                System.out.println(Thread.currentThread().getName() + "wait");
                a.wait();
                System.out.println(Thread.currentThread().getName() + "wait結(jié)束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
/*
Thread-0得到鎖
Thread-0wait
Thread-1得到鎖
Thread-1wait
Thread-2notifyAll
Thread-1wait結(jié)束
Thread-0wait結(jié)束
* */
/*
Thread-0得到鎖
Thread-0wait
Thread-1得到鎖
Thread-1wait
Thread-2notify
Thread-0wait結(jié)束
* */
  • 只釋放當(dāng)前monitor
  • 證明wait只釋放當(dāng)前的那把鎖
public class OwnMonitor {
    private static volatile Object a = new Object();
    private static volatile Object b = new Object();
    public static void main(String[] args) throws InterruptedException {
        Thread threadA = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (a) {
                    System.out.println("threadA得到a");
                    synchronized (b) {
                        System.out.println("threadA得到鎖b");

                        try {
                            System.out.println("threadA釋放a");
                            a.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        Thread threadB = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (a) {
                    System.out.println("threadB得到a");
                    System.out.println("threadB要獲取b");
                    synchronized (b) {
                        System.out.println("threadB得到b");
                    }
                }
            }
        });
        threadA.start();
        Thread.sleep(1000);
        threadB.start();
    }
}
/*
threadA得到a
threadA得到鎖b
threadA釋放a
threadB得到a
threadB要獲取b
* */

特點(diǎn)

  • 執(zhí)行這些方法必須先獲取鎖
  • notify只能換取一個(gè),而且是隨機(jī)的
  • 都屬于Object。任何對(duì)象都可以調(diào)用
  • 都是native final修飾的

當(dāng)線程從wait狀態(tài)剛被喚醒時(shí),通常不能直接得到鎖,那就會(huì)從waiting狀態(tài)轉(zhuǎn)換到blocked狀態(tài),搶到鎖之后狀態(tài)轉(zhuǎn)變?yōu)閞unnable

如果發(fā)生異常,則直接跳到Terminated狀態(tài)

通過(guò)wait notify方法實(shí)現(xiàn)生產(chǎn)者和消費(fèi)者

  • 將storge當(dāng)作生產(chǎn)者和消費(fèi)者進(jìn)行工作的倉(cāng)庫(kù)
  • 如果storge中沒(méi)有數(shù)據(jù),生產(chǎn)者就開(kāi)始wait
  • 如果storge中數(shù)據(jù)滿了,消費(fèi)者就開(kāi)始wait
  • 生產(chǎn)者和消費(fèi)者每進(jìn)行一次生產(chǎn)和消費(fèi),就執(zhí)行notify
public class ProducerConsumer {
    public static void main(String[] args) {
        Storge storge = new Storge();
        Producer producer = new Producer(storge);
        Consumer consumer = new Consumer(storge);
        new Thread(producer).start();
        new Thread(consumer).start();
    }
}
class Producer implements Runnable {
    private Storge storge;
    public Producer(Storge storge) {
        this.storge = storge;
    }
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            storge.put();
        }
    }
}
class Consumer implements Runnable {
    private Storge storge;
    public Consumer(Storge storge) {
        this.storge = storge;
    }
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            storge.take();
        }
    }
}
class Storge {
    private int maxSize;
    private LinkedList<Date> storge;
    public Storge() {
        maxSize = 10;
        storge = new LinkedList<>();
    }
    public synchronized void put() {
        while (storge.size() == maxSize) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        storge.add(new Date());
        System.out.println("已經(jīng)有了" + storge.size());
        notify();
    }
    public synchronized void take() {
        while (storge.size() == 0) {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("拿到了" + storge.poll() + "還剩" + storge.size());
        notify();
    }
}

sleep方法詳解

作用:讓線程在預(yù)期的時(shí)間執(zhí)行,其他時(shí)間不占用CPU資源

特點(diǎn):和wait不一樣,sleep不釋放鎖

sleep不會(huì)釋放鎖

證明sleep不會(huì)釋放 synchronized鎖

public class SleepSyn implements Runnable{
    public static void main(String[] args) {
        SleepSyn sleepSyn = new SleepSyn();
        new Thread(sleepSyn).start();
        new Thread(sleepSyn).start();
    }
    @Override
    public void run() {
        syn();
    }
    private synchronized void syn() {
        System.out.println(Thread.currentThread().getName() + "獲取鎖");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "釋放鎖");
    }
}
/*
* Thread-0獲取鎖
Thread-0釋放鎖
Thread-1獲取鎖
Thread-1釋放鎖
* */

證明sleep不釋放Lock鎖

public class sleepLock implements Runnable{
    private static final Lock LOCK = new ReentrantLock();
    @Override
    public void run() {
        LOCK.lock();
        System.out.println(Thread.currentThread().getName() + "獲取鎖");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            LOCK.unlock();
        }
        System.out.println(Thread.currentThread().getName() + "釋放鎖");
    }
    public static void main(String[] args) {
        sleepLock sleepLock = new sleepLock();
        new Thread(sleepLock).start();
        new Thread(sleepLock).start();
    }
}
/*
* Thread-0獲取鎖
Thread-0釋放鎖
Thread-1獲取鎖
Thread-1釋放鎖
* */

sleep響應(yīng)中斷

  • 拋出InterruptedException
  • 會(huì)清除中斷狀態(tài)
  • 中斷之后,拋出異常繼續(xù)執(zhí)行
public class sleepInterrupted implements Runnable{
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(new sleepInterrupted());
        thread.start();
        Thread.sleep(2000);
        thread.interrupt();
    }
    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println(new Date());
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                System.out.println("中斷");
                e.printStackTrace();
            }
        }
    }
}
/*
* Fri Jan 27 21:11:57 CST 2023
Fri Jan 27 21:11:58 CST 2023
中斷
Fri Jan 27 21:11:59 CST 2023
java.lang.InterruptedException: sleep interrupted
   at java.lang.Thread.sleep(Native Method)
   at java.lang.Thread.sleep(Thread.java:340)
   at java.util.concurrent.TimeUnit.sleep(TimeUnit.java:386)
   at com.jx.JavaTest.ThreadObjectMethod.sleepInterrupted.run(sleepInterrupted.java:21)
   at java.lang.Thread.run(Thread.java:748)
Fri Jan 27 21:12:00 CST 2023
Fri Jan 27 21:12:01 CST 2023
Fri Jan 27 21:12:02 CST 2023
Fri Jan 27 21:12:03 CST 2023
Fri Jan 27 21:12:04 CST 2023
Fri Jan 27 21:12:05 CST 2023
Fri Jan 27 21:12:06 CST 2023
Process finished with exit code 0
* */

總結(jié)

sleep方法可以讓線程進(jìn)入waiting狀態(tài),不占用CPU資源,但是不釋放鎖,規(guī)定時(shí)間之后再運(yùn)行

休眠期間如果被打斷,會(huì)拋出異常并清除中斷狀態(tài)

join方法詳解

新線程加入,主線程等子線程執(zhí)行完畢

代碼展示

  • 前一個(gè)結(jié)果是使用join
  • 后一個(gè)結(jié)果是沒(méi)使用join
  • 可知使用join之后,主線程會(huì)等join的線程執(zhí)行完畢再繼續(xù)執(zhí)行
public class join {
    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "執(zhí)行完畢");
            }
        });
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName() + "執(zhí)行完畢");
            }
        });
        thread1.start();
        thread2.start();
        System.out.println("開(kāi)始等待子線程運(yùn)行");
//        thread1.join();
//        thread2.join();
        System.out.println("所有線程執(zhí)行完畢");
    }
}
/*
* 開(kāi)始等待子線程運(yùn)行
Thread-0執(zhí)行完畢
Thread-1執(zhí)行完畢
所有線程執(zhí)行完畢
* */
/*
* 開(kāi)始等待子線程運(yùn)行
所有線程執(zhí)行完畢
Thread-1執(zhí)行完畢
Thread-0執(zhí)行完畢
* */
  • 遇到中斷
  • 第一個(gè)的運(yùn)行結(jié)果是主線程沒(méi)中斷的打印結(jié)果
  • 第二個(gè)的運(yùn)行結(jié)果是join期間進(jìn)行中斷的打印結(jié)果,可知在打印了“子線程運(yùn)行完畢”之后,依然打印了“啟動(dòng)”兩個(gè)字,可知會(huì)造成運(yùn)行混亂
  • 可以在捕獲異常的代碼塊中,將join的線程也中斷,可以解決上面的問(wèn)題
public class joinInterrupt {
    public static void main(String[] args) {
        Thread main1 = Thread.currentThread();
        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    main1.interrupt();
                    Thread.sleep(2000);
                    System.out.println("啟動(dòng)");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread1.start();
        System.out.println("join");
        try {
            thread1.join();
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + "中斷");
            // thread1.interrupt();
            e.printStackTrace();
        }
        System.out.println("子線程運(yùn)行完畢");
    }
}
/*
* join
啟動(dòng)
子線程運(yùn)行完畢
* */
/*
* join
main中斷
子線程運(yùn)行完畢
java.lang.InterruptedException
   at java.lang.Object.wait(Native Method)
   at java.lang.Thread.join(Thread.java:1252)
   at java.lang.Thread.join(Thread.java:1326)
   at com.jx.JavaTest.ThreadObjectMethod.joinInterrupt.main(joinInterrupt.java:23)
啟動(dòng)
Process finished with exit code 0
* */
/*
* join
main中斷
子線程運(yùn)行完畢
java.lang.InterruptedException: sleep interrupted
   at java.lang.Thread.sleep(Native Method)
   at com.jx.JavaTest.ThreadObjectMethod.joinInterrupt$1.run(joinInterrupt.java:13)
   at java.lang.Thread.run(Thread.java:748)
java.lang.InterruptedException
   at java.lang.Object.wait(Native Method)
   at java.lang.Thread.join(Thread.java:1252)
   at java.lang.Thread.join(Thread.java:1326)
   at com.jx.JavaTest.ThreadObjectMethod.joinInterrupt.main(joinInterrupt.java:23)
Process finished with exit code 0
* */

join期間,線程處于WAITING狀態(tài)

public class joinStates {
    public static void main(String[] args) throws InterruptedException {
        Thread main1 = Thread.currentThread();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                    System.out.println(main1.getState());
                    System.out.println("子線程運(yùn)行結(jié)束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        thread.start();
        System.out.println("join");
        thread.join();
        System.out.println("運(yùn)行完畢");
    }
}
/*
* join
WAITING
子線程運(yùn)行結(jié)束
運(yùn)行完畢
* */

yield方法

用來(lái)釋放CPU時(shí)間片,但是不一定能達(dá)到預(yù)期的效果,因?yàn)橛袝r(shí)CPU資源不緊張,無(wú)需yield

和sleep的區(qū)別是:sleep期間不會(huì)被再次調(diào)度但是yield會(huì)立刻處于競(jìng)爭(zhēng)狀態(tài),還會(huì)隨時(shí)再次被調(diào)度

到此這篇關(guān)于Java Thread多線程開(kāi)發(fā)中Object類詳細(xì)講解的文章就介紹到這了,更多相關(guān)Java Object類內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java加解密技術(shù)系列之RSA詳解

    Java加解密技術(shù)系列之RSA詳解

    出于安全考慮,網(wǎng)絡(luò)的傳輸中經(jīng)常對(duì)傳輸數(shù)據(jù)做加密和編碼處理,本篇文章主要介紹Java加解密技術(shù)系列之RSA詳解,非常具有實(shí)用價(jià)值,需要的朋友可以參考下。
    2016-10-10
  • 實(shí)例講解Java的設(shè)計(jì)模式編程中責(zé)任鏈模式的運(yùn)用

    實(shí)例講解Java的設(shè)計(jì)模式編程中責(zé)任鏈模式的運(yùn)用

    這篇文章主要介紹了Java的設(shè)計(jì)模式編程中責(zé)任鏈模式的運(yùn)用,講解了通過(guò)條件判斷結(jié)構(gòu)來(lái)分配不同對(duì)象的責(zé)任權(quán)限,需要的朋友可以參考下
    2016-02-02
  • 如何使用jmeter錄制瀏覽器Https請(qǐng)求過(guò)程圖解

    如何使用jmeter錄制瀏覽器Https請(qǐng)求過(guò)程圖解

    這篇文章主要介紹了基于jmeter錄制瀏覽器Https請(qǐng)求過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • SpringBoot + MapStruct 屬性映射工具的使用詳解

    SpringBoot + MapStruct 屬性映射工具的使用詳解

    MapStruct 是一個(gè)代碼生成器,簡(jiǎn)化了不同的 Java Bean 之間映射的處理,所謂的映射指的就是從一個(gè)實(shí)體變化成一個(gè)實(shí)體。接下來(lái)通過(guò)本文給大家介紹SpringBoot + MapStruct 屬性映射工具的使用,需要的朋友可以參考下
    2021-09-09
  • Gradle構(gòu)建基本的Web項(xiàng)目結(jié)構(gòu)

    Gradle構(gòu)建基本的Web項(xiàng)目結(jié)構(gòu)

    這篇文章主要為大家介紹了Gradle創(chuàng)建Web項(xiàng)目基本的框架結(jié)構(gòu)搭建,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-03-03
  • 帶你詳細(xì)了解Spring Security的注解方式開(kāi)發(fā)

    帶你詳細(xì)了解Spring Security的注解方式開(kāi)發(fā)

    這篇文章主要介紹了詳解spring security四種實(shí)現(xiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-08-08
  • Java System類用法實(shí)戰(zhàn)案例

    Java System類用法實(shí)戰(zhàn)案例

    這篇文章主要介紹了Java System類用法,結(jié)合具體實(shí)例形式分析了java使用System類獲取系統(tǒng)環(huán)境變量信息相關(guān)操作技巧,需要的朋友可以參考下
    2019-07-07
  • Java 本地方法Native Method詳細(xì)介紹

    Java 本地方法Native Method詳細(xì)介紹

    這篇文章主要介紹了 Java 本地方法Native Method詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • java獲取IP和IP的歸屬地的方法實(shí)踐

    java獲取IP和IP的歸屬地的方法實(shí)踐

    在Java中獲取IP地址通常指的是獲取本地機(jī)器的IP地址或者通過(guò)某種方式獲取的遠(yuǎn)程IP地址,本文就來(lái)詳細(xì)的介紹一下,感興趣的可以了解一下
    2024-05-05
  • Java異常體系非正常停止和分類

    Java異常體系非正常停止和分類

    這篇文章主要介紹了Java異常體系非正常停止和分類,指的是程序在執(zhí)行過(guò)程中,出現(xiàn)的非正常的情況,最終會(huì)導(dǎo)致JVM的非正常停止更多相關(guān)內(nèi)容需要的朋友可以參考一下
    2022-06-06

最新評(píng)論