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

聊聊Object類中的wait()和notify()方法

 更新時間:2021年09月27日 10:26:17   作者:百了江  
這篇文章主要介紹了Object類中的wait()和notify()方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Object類中的wait()和notify()方法

一、特點

wait()和notify()方法并不是線程對象的方法,是Java中任何一個Java對象都有的方法,并不特殊。

二、wait()方法的作用

Object obj = new Object();
obj.wait();

表示:obj.wait();方法的調(diào)用,會讓“當前線程(正在obj對象上活動的線程)”進入等待狀態(tài)。

三、notify()方法的作用

Object obj = new Object();
obj.notify();

表示:喚醒正在obj對象上等待的線程。

補充:

Object obj = new Object();
obj.notifyAll();

表示:喚醒正在obj對象上等待的所有線程。

四、wait()和notify()的使用

wait()和notify()方法都是建立在synchronized線程同步的基礎(chǔ)之上

重點

obj.wait()方法會讓正在obj對象上活動的當前線程進入等待狀態(tài),并且釋放之前占有的obj對象的鎖。

obj.notify()方法只會通知,不會釋放之前占有的obj對象的鎖。

object中的wait和notify細節(jié)

wait

jdk源碼:

在這里插入圖片描述

重點看下劃線的地方,是不是有些不理解。有個印象我們繼續(xù)往下看。

public class resourse {
    private Integer number = 0 ;
    /**
     * 用if為啥不行
     * 1:首先一點我們要搞清楚 wait操作會釋放鎖
     * 2:想想這種情況,當一個生產(chǎn)者線程執(zhí)行的時候 if number!=0 (此時的number為1 ) 就會發(fā)生阻塞 這時候
     * 釋放出鎖 這時候又一個生產(chǎn)者進程進來又會被wait住.然后一個生產(chǎn)者進程進來,消費了一個 但是notifyall 將所有的進程
     * 都解開了 。。那兩個生產(chǎn)者進程就會直接運行if后面的東西并沒有被拉回來重新判斷一下。這樣就造成了number的值變成2.同理number
     * 變成負數(shù)也是有可能的(兩個消費者進程先進來都堵塞).
     *
     *
     *
     *
     * @throws Exception
     */
    public synchronized void  produce () throws Exception
    {
//        判斷  這里用while 用if多與兩個線程容易出錯
//        不等于0就要等待消費者消費完
         if(number!=0)
         {
             this.wait();
         }
//         干活
        number++;
        System.out.println(Thread.currentThread().getName() + "的資源數(shù)為:" + number.toString());
//        釋放
        this.notifyAll();
    }
//wait操作會釋放鎖
    public synchronized void consumer () throws Exception
    {
        //    等于零就要等待生產(chǎn)者生產(chǎn)
        if (number == 0)
        {
            this.wait();
        }
//        消費
        number--;
        System.out.println(Thread.currentThread().getName() + "的資源數(shù)為:" + number.toString());
//        釋放
        this.notifyAll();
    }
}

調(diào)用者。這里開啟了兩個生產(chǎn)者和兩個消費者線程。生產(chǎn)者線程都執(zhí)行100次的produce,消費者線程都執(zhí)行100次的consumer

public class main {
    public static void main (String[] args) {
        resourse resourse = new resourse();
            new Thread(()->{
                try{
                    for (int i=0 ; i<100;i++)
                    resourse.produce();
                }catch (Exception e)
                {
                    e.printStackTrace();
                }
            }).start();
        new Thread(()->{
            try{
                for (int i=0 ; i<100;i++)
                resourse.produce();
            }catch (Exception e)
            {
                e.printStackTrace();
            }
        }).start();
        new Thread(()->{
            try{
                for (int i=0 ; i<100;i++)
                    resourse.consumer();
            }catch (Exception e)
            {
                e.printStackTrace();
            }
        }).start();
        new Thread(()->{
            try{
                for (int i=0 ; i<100;i++)
                resourse.consumer();
            }catch (Exception e)
            {
                e.printStackTrace();
            }
        }).start();
    }
}

我要說的重點是:

在這里插入圖片描述

這樣設(shè)計真的合理嗎?

jdk中為啥要規(guī)定我們要使用while,而不是if?

用if為啥不行

1:首先一點我們要搞清楚 wait操作會釋放鎖

2:想想這種情況,當一個生產(chǎn)者線程執(zhí)行的時候 if number!=0 (此時的number為1 ) 就會發(fā)生阻塞 這時候釋放出鎖 這時候又一個生產(chǎn)者進程進來又會被wait住.然后一個生產(chǎn)者進程進來,消費了一個 但是notifyall 將所有的進程都解開了 。。那兩個生產(chǎn)者進程就會直接運行if后面的東西并沒有被拉回來重新判斷一下。這樣就造成了number的值變成2.同理number變成負數(shù)也是有可能的(兩個消費者進程先進來都堵塞).

這個問題絕對是干貨,在工作中絕對會遇到生產(chǎn)者消費者問題,不少程序員會在這個地方踩坑。面試的時候如果考到你這個地方,你能解答出深層原理來。相信面試官會高看你一眼。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 圖解Java?ReentrantLock的條件變量Condition機制

    圖解Java?ReentrantLock的條件變量Condition機制

    想必大家都使用過wait()和notify()這兩個方法把,他們主要用于多線程間的協(xié)同處理。而RenentrantLock也支持這樣條件變量的能力,而且相對于synchronized?更加強大,能夠支持多個條件變量,本文就來詳細說說
    2022-10-10
  • IDEA+Maven搭建Spring環(huán)境的詳細教程

    IDEA+Maven搭建Spring環(huán)境的詳細教程

    這篇文章主要介紹了IDEA+Maven搭建Spring環(huán)境的詳細教程,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • Spring Aware標記接口使用案例解析

    Spring Aware標記接口使用案例解析

    這篇文章主要介紹了Spring Aware標記接口使用案例,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-04-04
  • C# log4net使用案例詳解

    C# log4net使用案例詳解

    這篇文章主要介紹了C# log4net使用案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • java中Ajax與Axios的使用小結(jié)

    java中Ajax與Axios的使用小結(jié)

    在項目中我們經(jīng)常會遇到需要向請求頭中添加消息的場景,本文主要介紹了java中Ajax與Axios的使用小結(jié),文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2024-02-02
  • Java獲取Excel中圖片所在的行和列坐標位置

    Java獲取Excel中圖片所在的行和列坐標位置

    這篇文章主要介紹了Java獲取Excel中圖片所在的行和列坐標位置,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的朋友可以參考一下
    2022-08-08
  • Spring WebFlux的使用指南

    Spring WebFlux的使用指南

    這篇文章主要介紹了Spring WebFlux的使用指南,幫助大家更好的理解和學習使用Spring框架,感興趣的朋友可以了解下
    2021-05-05
  • java反射拼接方法名動態(tài)執(zhí)行方法實例

    java反射拼接方法名動態(tài)執(zhí)行方法實例

    下面小編就為大家?guī)硪黄猨ava反射拼接方法名動態(tài)執(zhí)行方法實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • 解決微服務(wù)feign調(diào)用添加token的問題

    解決微服務(wù)feign調(diào)用添加token的問題

    這篇文章主要介紹了解決微服務(wù)feign調(diào)用添加token的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 學習SpringMVC——如何獲取請求參數(shù)詳解

    學習SpringMVC——如何獲取請求參數(shù)詳解

    本篇文章主要介紹了SpringMVC——如何獲取請求參數(shù)詳解,詳細的介紹了每種參數(shù)注解的用法。具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2016-12-12

最新評論