最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Thread.sleep(0)的寫法原理深入解析

 更新時間:2022年12月27日 14:04:05   作者:JAVA旭陽  
這篇文章主要為大家介紹了Thread.sleep(0)的寫法原理深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

最近在網上看到了一段代碼,讓我感到很迷茫。他在代碼中使用了 Thread.sleep(0),讓線程休眠時間為0秒,具體代碼如下。

int i = 0;
while (i<10000000) {
    // business logic
    //prevent long time gc
    if (i % 3000 == 0) {
        try {
            Thread.sleep(0);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

sleep了0秒,不就是不睡覺嗎?我的第一反應是這段代碼沒什么用,但是看到他的注釋又引起了我的興趣。經過一番研究,看似無用的一段代碼,其實大有文章。

探索分析

為了找到原因,首先去看下sleep方法的javadoc,如下:

Causes the currently executing thread to sleep (temporarily ceaseexecution) for the specified number of milliseconds, subject tothe precision and accuracy of system timers and schedulers. The thread does not lose ownership of any monitors.

顯然沒有得到正確的答案,最后在詢問作者說是使用Thread.sleep(0)可以暫時釋放CPU時間線。

時間片循環(huán)調度算法

在操作系統(tǒng)中,CPU有很多競爭策略。Unix系統(tǒng)采用時間片循環(huán)調度算法。在該算法中,所有進程都被分組到一個隊列中。操作系統(tǒng)按順序為每個進程分配一定的時間,即允許進程運行的時間。如果在時間片結束時進程仍在運行,則CPU將被剝奪并分配給另一個進程,如果進程在時間片內阻塞或結束,則CPU立即切換。調度程序所要做的就是維護一個就緒進程表。當進程用完時間片時,它將被移到隊列的末尾。

上面的代碼中存在死循環(huán)。作者希望一直用一個線程來處理業(yè)務邏輯。如果Thread.sleep(0)不使用主動放棄CPU時間片,線程資源會一直被占用。眾所周知,GC 線程具有低優(yōu)先級,因此Thread.sleep(0)用于幫助 GC 線程嘗試競爭 CPU 時間片。但是為什么作者說可以防止long time GC呢?這就講到JVM的垃圾回收原理了。

GC的安全點

HotSpot虛擬機為例,JVM并不會在代碼指令流的任何位置暫停以啟動垃圾回收,而是強制執(zhí)行必須到達安全點才暫停。換句話說,在到達安全點之前,JVM 不會為 GC STOP THE WORLD

JVM 會在一些循環(huán)跳轉和方法調用上設置安全點。不過,為了避免安全點過多帶來的沉重負擔,HotSpot虛擬機還有一個針對循環(huán)的優(yōu)化措施。如果循環(huán)次數少,執(zhí)行時間不宜過長。因此,默認情況下不會將使用 int 或更小數據類型作為索引值的循環(huán)放置在安全點中。這種循環(huán)稱為可數循環(huán)。相應地,使用long或更大范圍的數據類型作為索引值的循環(huán)稱為未計數循環(huán),將被放置在安全點。

但是,我們這里正好有一個可數循環(huán),所以我們的代碼不會放在安全點。因此,GC線程必須等到線程執(zhí)行完畢,才能執(zhí)行到最近的安全點。但如果使用Thread.sleep(0),則可以在代碼中放置一個安全點。我們可以看下HotSpotsafepoint.cpp源碼中的注釋,做除了說明。

// Begin the process of bringing the system to a safepoint.
// Java threads can be in several different states and are
// stopped by different mechanisms:
//
//  1. Running interpreted
//     The interpeter dispatch table is changed to force it to
//     check for a safepoint condition between bytecodes.
//  2. Running in native code
//     When returning from the native code, a Java thread must check
//     the safepoint _state to see if we must block.  If the
//     VM thread sees a Java thread in native, it does
//     not wait for this thread to block.  The order of the memory
//     writes and reads of both the safepoint state and the Java
//     threads state is critical.  In order to guarantee that the
//     memory writes are serialized with respect to each other,
//     the VM thread issues a memory barrier instruction
//     (on MP systems).  In order to avoid the overhead of issuing
//     a memory barrier for each Java thread making native calls, each Java
//     thread performs a write to a single memory page after changing
//     the thread state.  The VM thread performs a sequence of
//     mprotect OS calls which forces all previous writes from all
//     Java threads to be serialized.  This is done in the
//     os::serialize_thread_states() call.  This has proven to be
//     much more efficient than executing a membar instruction
//     on every call to native code.
//  3. Running compiled Code
//     Compiled code reads a global (Safepoint Polling) page that
//     is set to fault if we are trying to get to a safepoint.
//  4. Blocked
//     A thread which is blocked will not be allowed to return from the
//     block condition until the safepoint operation is complete.
//  5. In VM or Transitioning between states
//     If a Java thread is currently running in the VM or transitioning
//     between states, the safepointing code will wait for the thread to
//     block itself when it attempts transitions to a new state.

可以看上面的第2點 Running in native code,而Thread.sleep(long millis)是一種native方法。

總結

Thread.sleep(0)不是什么無用的代碼。sleep 方法可用于在 java 代碼中放置一個安全點??梢蕴崆霸陂L循環(huán)中觸發(fā)GC,避免GC線程長時間等待,從而避免達到拉長GC時間的目的。

以上就是Thread.sleep(0)的寫法原理深入解析的詳細內容,更多關于Thread.sleep(0)寫法原理的資料請關注腳本之家其它相關文章!

相關文章

  • SpringBoot實現devtools實現熱部署過程解析

    SpringBoot實現devtools實現熱部署過程解析

    這篇文章主要介紹了SpringBoot實現devtools實現熱部署過程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • Spring框架實現AOP添加日志記錄功能過程詳解

    Spring框架實現AOP添加日志記錄功能過程詳解

    這篇文章主要介紹了Spring框架實現AOP添加日志記錄功能過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • JAVA并發(fā)編程有界緩存的實現詳解

    JAVA并發(fā)編程有界緩存的實現詳解

    這篇文章主要介紹了JAVA并發(fā)編程有界緩存的實現詳解的相關資料,這里舉例說明如何實現,四種方法一一代碼實現,需要的朋友可以參考下
    2016-12-12
  • 大模型chat/completions和completions區(qū)別解析

    大模型chat/completions和completions區(qū)別解析

    OpenAI的completions和chat/completions是兩個不同的端點,completions用于單次文本補全,而chat/completions用于多輪對話生成,選擇哪個端點取決于你的具體需求,本文介紹大模型chat/completions和completions區(qū)別,感興趣的朋友一起看看吧
    2025-03-03
  • Java日期類詳解(最新推薦)

    Java日期類詳解(最新推薦)

    早期版本主要使用?java.util.Date、java.util.Calendar?等類,Java?8及以后引入了新的日期和時間API(JSR?310),包含在java.time包中,本文給大家介紹Java日期類的相關知識,感興趣的朋友一起看看吧
    2025-06-06
  • SpringBoot服務設置禁止server.point端口的使用

    SpringBoot服務設置禁止server.point端口的使用

    本文主要介紹了SpringBoot服務設置禁止server.point端口的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01
  • 基于Netty實現WebSocket的常用處理器及區(qū)別解析

    基于Netty實現WebSocket的常用處理器及區(qū)別解析

    文章介紹了Netty中的ChannelInboundHandlerAdapter和SimpleChannelInboundHandler處理器,以及WebSocket的幾種常見幀類型,本文給大家介紹的非常詳細,感興趣的朋友一起看看吧
    2025-02-02
  • Java獲取視頻時長和封面截圖

    Java獲取視頻時長和封面截圖

    這篇文章主要為大家詳細介紹了如何使用Java獲取視頻時長和封面截圖功能,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下
    2025-03-03
  • Java項目防止SQL注入的幾種方式

    Java項目防止SQL注入的幾種方式

    SQL注入是一種常見的攻擊方式,黑客試圖通過操縱應用程序的輸入來執(zhí)行惡意SQL查詢,從而繞過認證和授權,竊取、篡改或破壞數據庫中的數據,本文主要介紹了Java項目防止SQL注入的幾種方式,感興趣的可以了解一下
    2023-12-12
  • Java8中方便又實用的Map函數總結

    Java8中方便又實用的Map函數總結

    java8之后,常用的Map接口中添加了一些非常實用的函數,可以大大簡化一些特定場景的代碼編寫,提升代碼可讀性,快跟隨小編一起來看看吧
    2022-11-11

最新評論

霍邱县| 焦作市| 临潭县| 中超| 慈利县| 桐庐县| 新蔡县| 阳曲县| 竹溪县| 永丰县| 马尔康县| 玉溪市| 昌都县| 博罗县| 康乐县| 郯城县| 陕西省| 峨眉山市| 杭州市| 哈尔滨市| 临猗县| 旬阳县| 隆安县| 高雄县| 凤凰县| 九台市| 花莲县| 安吉县| 墨脱县| 白河县| 府谷县| 偏关县| 凤凰县| 鲁甸县| 阿克苏市| 大姚县| 黑龙江省| 衢州市| 苏尼特右旗| 教育| 大同市|