成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

阿里面試官問我Java線程和操作系統線程什么關系

系統
這個問題是安琪拉之前面試被問到的一個問題,正好順著上一篇文章介紹完線程調用時的用戶態和內核態的切換,后續把Java 并發的都一起講了。

[[376045]]

本文轉載自微信公眾號「安琪拉的博客」,作者安琪拉的博客 。轉載本文請聯系安琪拉的博客公眾號。

 這個問題是安琪拉之前面試被問到的一個問題,正好順著上一篇文章介紹完線程調用時的用戶態和內核態的切換,后續把Java 并發的都一起講了。

面試官:聽前一個面試官說你Java并發這塊掌握的不錯,我們深入的交流一下;

我: 看了看面試官頭部稀疏的結締組織,已然覺得這場面試不簡單,不過好在事前把安琪拉的博客看了個遍,有所準備,我回答說:咳咳,掌握的還算可以。

面試官:Java線程用過的吧?

我:用過。

面試官:那你給我講講Java線程和操作系統的?

我:啊!!!

劇情不應該這樣的啊,開場不應該先是 synchronized 或者 volatile,再然后是線程池和AQS,怎么上來就整這玩意。

我:好的,那我分三段講,

  • 用戶態的線程
  • 內核態的線程
  • Java 線程源碼

1. 用戶態的線程

第一階段:

其實早期的時候,操作系統是沒有線程的概念,線程是后面加進來的,操作系統剛開始只有進程,操作系統分配資源的最小單位是進程,進程與進程之間相關隔離,每個進程有自己的內存空間,文件描述符,CPU調度以進程作為最小調度單元;

第二階段:

初期的多線程,線程是在用戶空間下實現的。

什么意思?我們都知道內存分用戶空間和系統空間,系統空間是給操作系統使用的,用戶空間是應用程序使用的,應用程序如果需要訪問系統空間,需要進行系統調用,從用戶態切換到內核態,這里詳細可以參考我上一篇文章: [講講用戶空間和內核空間]

那怎么在用戶空間實現的多線程呢?

實際上是操作系統按進程維度來調度,操作系統是不去管你用戶線程的切換的,應用程序自己在用戶空間實現線程的創建、維護和調度。模型如下圖:

當線程在用戶空間下實現時,操作系統對線程的存在一無所知,操作系統只能看到進程,而不能看到線程。所有的線程都是在用戶空間實現。在操作系統看來,每一個進程只有一個線程。

這種方式的好處之一就是即使操作系統不支持線程,也可以通過庫函數來支持線程。在JDK1.1中,就用的綠色線程,而不是原始線程。

下面是關于green thread的解釋,因為green thread不是今天的重點,就不細說了。

green threads 是一種由運行環境或虛擬機(VM)調度,而不是由本地底層操作系統調度的線程。綠色線程并不依賴底層的系統功能,模擬實現了多線程的運行,這種線程的管理調配發生在用戶空間而不是內核空間,所以它們可以在沒有原生線程支持的環境中工作。

在Java 1.1中,綠色線程(至少在 Solaris 上)是JVM 中使用的唯一一種線程模型。由于綠色線程和原生線程比起來在使用時有一些限制,隨后的 Java 版本中放棄了綠色線程,轉而使用native threads。

這種模式的優點和缺點都非常明顯:

缺點: 因為操作系統不知道線程的存在,CPU的時間片切換是以進程為維度的,如果進程中有某個線程進行了某些耗時長的操作,會阻塞整個進程。另外當一個進程中的某一個線程(綠色線程)進行系統調用時,比如網絡IO、缺頁中斷等操作而導致線程阻塞,操作系統也會阻塞整個進程,即使這個進程中其它線程還在工作。

優點: 使用庫函數來實現的線程切換,就免去了用戶態到內核態的切換,這個味道熟不熟,對了,Go的協程就有借鑒了一部分這個思想。

2. 內核態的線程

在 Java1.2 之后. Linux中的JVM是基于pthread實現的, 可以直接說 Java 線程就是依賴操作系統實現的,是1:1的關系。

現在的Java中線程的本質,其實就是操作系統中的線程

另外我看很多資料上說 Java線程的實現采用的是LWP(輕量級進程),實際上從Linux 內核2.6開始,就把LinuxThread 換成了新的線程實現方式NPTL,NPTL解決了LinuxThread中絕大多數跟POSIX標準不兼容的特性,并提供了更好的性能,可擴展性及可維護性等等。

LinuxThread使用的是1 * 1模型,即每一個用戶態線程都有一個內核的管理實體跟其對應,這個內核對應的管理實體就是進程,又稱LWP(輕量級進程)

希望了解更多NPTL的可以去看詳細介紹NPTL.

我們知道,每個線程都有它自己的線程上下文,線程上下文包括線程的ID、棧、程序計數器、通用的寄存器等的合集。總覺得上下文這個詞很模棱二可,但是發現也找不到更合適的詞來描述。

線程有自己的獨立的上下文,由操作系統調度,但是也有一個缺點,那就是線程消耗資源太大了,例如在linux上,一個線程默認的棧大小是1M,單機創建幾萬個線程就有點吃力了。所以后來在編程語言的層面上,就出現了協程這個東西。

協程的模式有點類似結合了上面二種方式,即是在用戶態做線程資源切換,也讓操作系統在內核層做線程調度。

協程跟操作系統的線程是有映射關系的,例如我們建了m個協程,需要在N個線程上執行,這就是m: n的方案,這n個線程也是靠操作系統調度實現。

另外協程是按需使用棧內存的,所以理論上可以輕輕松松創建百萬級的協程。

目前協程這塊支持的最好的是go語言, 不過現在OpenJDK社區也正在為JDK增加協程的支持。

3. 線程的源碼

我們在Java中調用 new Thread(Runnable ***).start() 方法時,怎么從用戶態切到內核態,發送系統調用,在操作系統內核層中創建一個線程的呢?

這個可以一步步往下鉆,關鍵點最后在JVM層系統調用pthread_create創建線程。

首先是native方法: private native void start0();

下到Thread.c 文件,:

OpenJDK1.8源代碼第44行,方法映射;追著 JVM_StartThread 進到 jvm.cpp

linux 系統下的,看 src/hotspot/os/linux/os_linux.cpp

主要關注 pthread_create 這里,是通過linux 的 c庫函數完成系統調用,從用戶態切到內核態完成線程的創建。

文中源代碼地址:

  1. Thread.c 
  2.  
  3. pthread_create 
  4.  
  5. os_linux 

 

責任編輯:武曉燕 來源: 安琪拉的博客
相關推薦

2023-12-20 14:35:37

Java虛擬線程

2021-05-08 07:53:33

面試線程池系統

2023-11-06 17:39:35

JavaArrayList線程

2024-09-11 22:51:19

線程通訊Object

2020-10-26 07:07:50

線程安全框架

2021-04-19 09:27:03

Java線程操作系統

2021-12-02 08:19:06

MVCC面試數據庫

2024-04-10 09:47:59

Java調度虛擬線程

2021-06-03 08:55:54

分布式事務ACID

2022-11-25 17:29:27

分布式事務

2024-04-02 09:45:27

線程池Executors開發

2022-06-02 09:29:55

線程組線程樹狀結構

2021-09-27 07:11:18

MySQLACID特性

2024-03-11 18:18:58

項目Spring線程池

2024-09-09 15:09:30

2021-08-12 14:49:44

操作系統線程進程

2020-04-16 08:22:11

HTTPS加解密協議

2021-05-20 08:54:16

Go面向對象

2010-08-23 15:06:52

發問

2021-04-25 09:36:20

Go協程線程
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久专区| 精品无码三级在线观看视频 | 日韩精品在线观看免费 | 日韩在线免费视频 | 国产乱码精品一区二区三区av | 不卡视频一区 | 在线观看日韩精品视频 | 毛片在线看片 | 欧美激情久久久 | 日韩亚洲一区二区 | 视频第一区| 中文字幕 在线观看 | 精品二 | 日韩一区二区在线免费观看 | 国产小视频在线 | 日屁网站 | 亚洲一在线 | 产真a观专区 | 嫩草影院网址 | 欧美激情亚洲激情 | 久久成人国产精品 | 成人福利在线 | 免费在线日韩 | 特级黄色毛片 | 国产精品揄拍一区二区 | 夜夜夜久久 | 99热国产精品| h视频在线播放 | 免费成人av | 中文字幕欧美在线观看 | 亚洲福利免费 | 四虎在线播放 | 黄网站涩免费蜜桃网站 | 中文字幕动漫成人 | 日日操日日干 | 在线中文字幕av | 久久久这里都是精品 | 国产免费福利在线 | 欧美a免费 | 一区二区三区在线播放视频 | 亚州成人|