多線程編程中的鎖策略

目錄

1.悲觀鎖vs樂觀鎖

關鍵總結

悲觀鎖:

樂觀鎖:

選擇建議

用?悲觀鎖?當:

用?樂觀鎖?當:

2.重量級鎖vs輕量級鎖?

選擇建議

用?輕量級鎖:

用?重量級鎖:

3.掛起等待鎖vs自旋鎖

?關鍵細節說明

選擇建議

4.普通互斥鎖vs讀寫鎖

? ? ? ?讀寫鎖互斥規則詳解

? ? ? ?普通互斥鎖 vs 讀寫鎖對比

5.可重入鎖vs不可重入鎖?

選擇建議

6.公平鎖vs不公平鎖

1)?公平鎖和不公平鎖的對比

2)選擇建議

7.鎖升級

8.鎖優化

9.鎖的粗化

10.synchronized

11.reentrantlock和synchronized的對比


鎖策略(Locking Strategies)是多線程編程中用于控制并發訪問共享資源的核心機制。不同的鎖策略在性能、公平性、復雜度等方面有顯著差異。


以下來介紹幾組常見的鎖策略:

1.悲觀鎖vs樂觀鎖

悲觀鎖:在加鎖的時候預測接下來的競爭會非常激烈,所以就需要針對這種激烈的競爭情況做一些準備工作:每次拿數據的時候都會上鎖,這樣別人想要拿數據的時候就會阻塞知道它拿到鎖。

樂觀鎖:在加鎖的時候預測接下來的競爭不會非常激烈,也就一般不會發生并發沖突,不必多做準備。在數據進行提交更新的時候再檢測是否產生并發沖突。

特性悲觀鎖樂觀鎖
核心思想假設并發沖突一定會發生,因此先加鎖再訪問數據。假設并發沖突較少發生,因此不加鎖,通過版本號/CAS機制檢測沖突。
實現方式直接加鎖(如?synchronizedReentrantLock、數據庫?SELECT FOR UPDATE)。無鎖機制(如?CAS、版本號校驗、AtomicXXX?類、數據庫?樂觀并發控制)。
阻塞行為??會阻塞其他線程(未獲取鎖的線程必須等待)。??無阻塞,線程直接操作數據,沖突時通過重試或回滾解決。
適用場景寫多讀少(如銀行轉賬、庫存扣減等強一致性場景)。讀多寫少(如緩存、統計計數等低沖突場景)。
性能開銷高(鎖競爭、上下文切換、死鎖風險)。低(無鎖競爭,但沖突頻繁時重試開銷增大)。
數據一致性強一致性(鎖內操作串行化)。最終一致性(沖突時需業務層處理)。
典型實現Java:?synchronizedReentrantLock
數據庫:?SELECT FOR UPDATE
Java:?AtomicIntegerStampedLock
數據庫:?版本號字段CAS操作
優缺點? 保證強一致性
? 吞吐量低,可能死鎖。
? 高并發性能
? 需處理沖突,可能活鎖或重試饑餓。

關鍵總結

  1. 悲觀鎖

    • “先保護再操作”,適合強一致性場景,但性能較差。

    • 例如:synchronized?關鍵字、數據庫行鎖。

  2. 樂觀鎖

    • “先操作再校驗”,適合高并發讀場景,沖突少時性能極高。

    • 例如:CAS?操作、StampedLock?的樂觀讀模式。


選擇建議

  • 用?悲觀鎖?當:

    • 寫操作頻繁,或沖突概率高(如支付系統)。

    • 業務邏輯復雜,需嚴格保證數據一致性。

  • 用?樂觀鎖?當:

    • 讀多寫少,且沖突概率低(如商品瀏覽統計)。

    • 追求高吞吐量,能容忍重試或短暫不一致。

2.重量級鎖vs輕量級鎖?

重量級鎖:應對悲觀的場景,此時就要付出更多的代價,更低效。

輕量級鎖:應對樂觀的場景,此時付出的代價更小,更高效。

特性重量級鎖輕量級鎖
鎖級別最高級別的鎖(如操作系統級互斥鎖)JVM 層面的優化鎖(基于 CAS 自旋)
實現原理通過操作系統內核的?互斥量(Mutex)?實現,涉及用戶態/內核態切換。通過?CAS(Compare-And-Swap)?和?線程棧中的鎖記錄(Lock Record)?實現。
阻塞方式未獲取鎖的線程會?直接掛起(進入內核態等待隊列),由操作系統調度喚醒。先通過?自旋(忙等待)?嘗試獲取鎖,失敗后才升級為重量級鎖。
性能開銷高(上下文切換、內核態切換、CPU 調度延遲)。低(無系統調用,僅在用戶態自旋)。
適用場景高競爭、長臨界區(如長時間持有鎖的復雜操作)。低競爭、短臨界區(如快速計算的簡單操作)。
鎖升級是鎖膨脹的最終狀態(輕量級鎖/偏向鎖失敗后升級)。是偏向鎖失敗后的中間狀態,可能進一步升級為重量級鎖。
典型例子synchronized?在競爭激烈時的最終狀態。synchronized?在低競爭時的優化狀態。
優點嚴格保證線程安全,適合高并發沖突場景。減少內核態開銷,提高短任務性能。
缺點吞吐量低,響應延遲高。自旋浪費 CPU(長時間自旋可能反而降低性能)。

選擇建議

  • 用?輕量級鎖

    • 代碼塊執行時間極短(如計數器遞增)。

    • 線程競爭概率低(如局部變量同步)。

  • 用?重量級鎖

    • 臨界區執行時間長(如數據庫事務)。

    • 競爭激烈(如全局緩存更新)。

3.掛起等待鎖vs自旋鎖

掛起等待鎖:(重量級鎖的經典實現)一旦發生競爭,獲取不到鎖,就進入阻塞狀態。

自旋鎖:(輕量級鎖的經典實現)一旦發生競爭,獲取不到鎖,就循環請求,也就是“忙等”。發生在“樂觀”情況下,鎖競爭很小,即使“忙等”,很快也能獲取鎖,等待的時間也不會很長?,消耗的資源也就不會很多。

特性掛起等待鎖(阻塞鎖)自旋鎖
實現原理獲取不到鎖時,線程進入阻塞狀態(WAITING),釋放CPU資源獲取不到鎖時,線程循環忙等待(自旋),不釋放CPU
響應速度較慢(需要線程切換和喚醒)極快(無上下文切換)
CPU占用低(線程掛起后不消耗CPU)高(持續占用CPU自旋)
適用場景鎖持有時間較長(如I/O操作、復雜計算)鎖持有時間極短(如CAS操作、簡單計算)
公平性通常支持公平鎖(按申請順序獲取鎖)通常是非公平鎖(競爭機制)
鎖升級可能涉及內核態切換(如synchronized重量級鎖)完全在用戶態運行(無系統調用)
典型實現Java的synchronized(競爭激烈時)、ReentrantLockJava的AtomicIntegerSpinLock(自定義實現)
優點節省CPU資源,適合高競爭場景無上下文切換,延遲極低
缺點線程切換開銷大,響應延遲高自旋過久會浪費CPU,可能饑餓
死鎖風險可能死鎖(需超時或中斷機制)無死鎖(但可能活鎖)

?關鍵細節說明

  1. 掛起等待鎖(阻塞鎖)

    • 適用場景:鎖競爭激烈或臨界區執行時間較長(如數據庫事務)。

    • 優化建議

      • 使用ReentrantLock替代synchronized(支持超時和中斷)。

      • 設置合理的鎖超時時間(避免死鎖)。

  2. 自旋鎖

    • 適用場景:鎖持有時間極短(如計數器遞增)。

    • 優化建議

      • 限制自旋次數(如JVM的-XX:PreBlockSpin參數)。

      • 升級為自適應自旋鎖(根據歷史自旋時間動態調整)。


選擇建議

  • 優先用自旋鎖

    • 臨界區代碼執行時間?< CPU上下文切換時間(通常約1μs)。

    • 例如:AtomicInteger的CAS操作。

  • 優先用掛起等待鎖

    • 臨界區代碼執行時間?> 自旋消耗的CPU時間

    • 例如:同步訪問數據庫連接池。

4.普通互斥鎖vs讀寫鎖

普通互斥鎖:鎖之間完全互斥,同一時間只能有一個線程持有鎖,分為‘加鎖’和‘解鎖’兩個過程。synchronized就是經典的普通互斥鎖。

讀寫鎖:應對某些讀多寫少的情況,分為“讀鎖”和“寫鎖”兩種,其中“讀鎖”和“讀鎖”之間不互斥,支持了多個線程同時讀取的情況,減少了鎖沖突的情況。

? ? ? ?讀寫鎖互斥規則詳解

  1. 讀鎖 vs 讀鎖

    • 不互斥:多個線程可同時持有讀鎖(共享)。

    • 示例:100個線程可同時讀取緩存數據。

  2. 讀鎖 vs 寫鎖

    • 完全互斥

      • 已有讀鎖時,寫鎖請求被阻塞(直到所有讀鎖釋放)。

      • 已有寫鎖時,讀鎖請求被阻塞(直到寫鎖釋放)。

  3. 寫鎖 vs 寫鎖

    • 完全互斥:同一時刻只允許一個寫鎖存在。

? ? ? ?普通互斥鎖 vs 讀寫鎖對比

特性普通互斥鎖(Mutex Lock)讀寫鎖(Read-Write Lock)
鎖模式排他鎖(Exclusive Lock)讀鎖(共享鎖) + 寫鎖(排他鎖)
并發性完全互斥,同一時刻只有一個線程能持有鎖讀鎖可共享(允許多線程同時讀),寫鎖互斥
適用場景寫操作頻繁或讀寫操作時間相近讀多寫少(如緩存、配置讀取)
性能高競爭下性能差讀并發高,寫操作會阻塞所有讀/寫
公平性支持公平/非公平(如ReentrantLock通常支持公平/非公平(如ReentrantReadWriteLock
鎖降級不支持支持(持有寫鎖的線程可以獲取讀鎖,再釋放寫鎖)
鎖升級不支持不支持(讀鎖不能直接升級為寫鎖,易死鎖)
實現復雜度簡單較復雜(需維護讀/寫狀態)
典型實現Java:?synchronizedReentrantLockJava:?ReentrantReadWriteLock
優點實現簡單,嚴格保證一致性讀操作高并發,適合讀多寫少場景
缺點讀寫均互斥,并發性差寫操作饑餓風險(長期有讀鎖時寫鎖無法獲取)

5.可重入鎖vs不可重入鎖?

可重入鎖:允許同一個線程多次獲取一把鎖。

不可重入鎖:不允許同一個線程多次獲取同一把鎖。

特性可重入鎖不可重入鎖
遞歸調用支持? 同一線程可重復獲取同一把鎖(計數器遞增)? 同一線程重復獲取會死鎖
死鎖風險低(允許嵌套加鎖)高(遞歸調用或嵌套加鎖直接死鎖)
實現復雜度較高(需維護持有線程和重入次數)簡單(僅檢查鎖是否被占用)
典型應用場景遞歸函數、同步方法調用其他同步方法簡單臨界區保護(無嵌套調用場景)
性能開銷略高(需維護重入狀態)較低(無狀態跟蹤)
鎖釋放要求必須釋放與獲取次數匹配(如加鎖3次需解鎖3次)只需釋放1次
公平性支持通常支持(如ReentrantLock(true)通常不支持
中斷響應支持(lockInterruptibly()一般不支持
實現示例Java:?synchronizedReentrantLock
C++:?std::recursive_mutex
Java: 自定義簡單鎖
C:?pthread_mutex(默認不可重入)
適用性通用場景(尤其是復雜同步邏輯)極簡場景(無嵌套/遞歸)

選擇建議

  • 用可重入鎖

    • 存在方法嵌套/遞歸調用同步代碼。

    • 使用類庫提供的鎖(如Java的synchronized)。

  • 用不可重入鎖

    • 絕對無嵌套的簡單臨界區(性能敏感場景)。

    • 需要極輕量級同步原語(如自定義自旋鎖)。

6.公平鎖vs不公平鎖

公平鎖:線程采用“先來后到”的思想來依次獲取鎖。

不公平鎖:線程采用“概率相等”的思想來獲取鎖。

1)?公平鎖和不公平鎖的對比

特性公平鎖 (Fair Lock)非公平鎖 (Non-Fair Lock)
獲取鎖順序嚴格按照線程請求順序(先到先得)允許插隊(新線程可能直接搶到鎖)
吞吐量較低(線程切換頻繁)較高(減少線程切換)
線程饑餓不會發生(保證每個線程有機會執行)可能發生(某些線程長期搶不到鎖)
實現復雜度較高(需維護等待隊列)較低(直接競爭)
適用場景要求嚴格公平性(如訂單處理、金融交易)高并發場景,追求性能(如緩存、計數器)
鎖獲取策略檢查是否有等待更久的線程,有則排隊直接嘗試獲取鎖,失敗才進入隊列
典型實現ReentrantLock(true)ReentrantLock(false)(默認)、synchronized
響應時間較穩定(按序執行)波動較大(可能某些線程更快)
CPU利用率較低(線程頻繁掛起/喚醒)較高(減少上下文切換)
鎖競爭激烈時所有線程按序執行,但吞吐量下降可能某些線程一直搶到鎖,其他線程等待更久

2)選擇建議

場景推薦鎖類型原因
需要嚴格順序(如交易系統)公平鎖避免某些請求被無限延遲
高并發、低延遲(如緩存)非公平鎖減少線程切換,提高吞吐量
線程執行時間差異大公平鎖防止短任務“餓死”長任務
鎖競爭不激烈非公平鎖插隊概率低,性能接近公平鎖但開銷更小

7.鎖升級

鎖升級是多線程并發控制中的一種優化策略,指JVM根據競爭情況動態調整鎖的級別,從低開銷鎖逐步升級為高開銷鎖的過程。

無鎖 → 偏向鎖 → 輕量級鎖 → 重量級鎖
鎖級別升級時機特點適用場景
無鎖對象未被任何線程鎖定新建對象
偏向鎖

代碼進入synchronized代碼塊

=>偏向鎖

僅記錄線程ID,無實際同步,只是一個標記,不是鎖單線程訪問
輕量級鎖

其他線程嘗試獲取這個鎖

=>輕量級鎖

CAS自旋嘗試獲取鎖低競爭多線程
重量級鎖

JVM發現,當前競爭鎖的情況非常激烈

=>重量級鎖

操作系統互斥量實現高競爭場景

總的來說,鎖升級是懶漢模式思想的一種體現,旨在減少開銷。鎖升級只升不降,不可以再轉化回去。

8.鎖優化

鎖優化是提升多線程程序性能的關鍵手段,JIT編譯器通過逃逸分析移除不必要的鎖。旨在減少鎖的開銷。

9.鎖的粗化

鎖粗化是JVM針對同步代碼的一種重要優化技術,它通過合并相鄰的同步塊減少不必要的鎖獲取/釋放操作,從而提升程序執行效率。

粒度級別含義
粗粒度在一把鎖之間代碼更多
細粒度在一把鎖之間代碼更少

?鎖的粗化實際上就是通過將多把鎖合并為一把鎖來減少頻繁上鎖、解鎖的開銷,使得一把鎖之間的代碼變得更多。

10.synchronized

鎖的類型synchronized
悲觀鎖還是樂觀鎖?自適應
重量級鎖還是輕量級鎖?自適應
掛起等待鎖還是自旋鎖?自適應
普通互斥鎖還是讀寫鎖?普通互斥鎖

可重入鎖還是不可重入鎖?

可重入鎖
公平鎖還是不公平鎖?公平鎖

11.reentrantlock和synchronized的對比

ReentrantLock 是 Java 并發包(java.util.concurrent.locks)中提供的可重入互斥鎖實現,它比傳統的 synchronized 關鍵字提供更靈活的鎖操作。?

以下是reentrantlocksynchronized的五點區別:

區別reentrantlocksynchronized
實現方式Java標準庫中的類,由JDK實現關鍵字,由JVM實現,JVM基于C++實現
加鎖方法通過lock()和unlock()方法加鎖和解鎖,有可能因為忘記解鎖而觸發線程安全問題通過代碼塊控制加鎖、解鎖
trylock()方法具備trylock()方法,嘗試獲取鎖而不會無限期阻塞不具備
公平鎖與非公平鎖默認是非公平鎖,但是也可以實現公平鎖非公平鎖
等待通知機制等待通知機制是condition類,比synchronized的wait、notify功能更為強大wait、notify

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/74868.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/74868.shtml
英文地址,請注明出處:http://en.pswp.cn/web/74868.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

負載均衡是什么,Kubernetes如何自動實現負載均衡

負載均衡是什么&#xff1f; 負載均衡&#xff08;Load Balancing&#xff09; 是一種網絡技術&#xff0c;用于將網絡流量&#xff08;如 HTTP 請求、TCP 連接等&#xff09;分發到多個服務器或服務實例上&#xff0c;以避免單個服務器過載&#xff0c;提高系統的可用性、可擴…

React-01React創建第一個項目(npm install -g create-react-app)

1. React特點 JSX是javaScript語法的擴展&#xff0c;React開發不一定使用JSX。單向響應的數據流&#xff0c;React實現單向數據流&#xff0c;減少重復代碼&#xff0c;比傳統數據綁定更簡單。等等 JSX是js的語法擴展&#xff0c;允許在js中編寫類似HTML的代碼 const …

小程序中的網絡請求

在小程序中&#xff0c;使用 wx.request( ) 這個方法來發送網路請求&#xff0c;整個請求的方式和 jQuery 里面的 $.ajax 方法是非常相似的。 在 wx.request( ) 這個方法中&#xff0c;接收一個配置對象&#xff0c;該配置對象中能夠配置的項目如下表&#xff1a; 關于服務器…

jvm 的attach 和agent機制

Java 的 Attach 和 Agent 機制在實際應用中得到了廣泛的成功應用&#xff0c;尤其是在監控、調試、性能分析、故障排查等方面。以下是這兩種機制在實際場景中的一些成功應用案例&#xff1a; 1. 性能監控與分析 Java Agent 和 Attach 機制廣泛應用于性能監控和分析&#xff0…

基于SpringBoot的“留守兒童網站”的設計與實現(源碼+數據庫+文檔+PPT)

基于SpringBoot的“留守兒童網站”的設計與實現&#xff08;源碼數據庫文檔PPT) 開發語言&#xff1a;Java 數據庫&#xff1a;MySQL 技術&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系統展示 系統整體功能圖 局部E-R圖 系統首頁界面 系統注冊…

iPhone XR:一代神機,止步于此

什么樣的 iPhone &#xff0c;才配稱為一代神機&#xff1f; 我曾經用過iPhone 4S、iPhone 6S Plus、iPhone 8 Plus&#xff0c;iPhone SE2、iPhone XR、iPhone 13、iPhone 14 Plus、iPhone 15/Pro。 不管硬件再怎么卷&#xff0c;不管囊中是否羞澀&#xff0c;主力機基本沒考…

【VUE】RuoYi-Vue3項目結構的分析

【VUE】RuoYi-Vue3項目結構的分析 1. 項目地址2. RuoYi-Vue3項目結構2.1 整體結構2.2 package.json2.2.1 &#x1f9fe; 基本信息2.2.2 &#x1f527; 腳本命令&#xff08;scripts&#xff09;2.2.3 &#x1f30d; 倉庫信息2.2.4 &#x1f4e6; 項目依賴&#xff08;dependenc…

架構師面試(二十五):分布式存儲 Leader 設計

問題 在非常多的分布式存儲系統中&#xff0c;如&#xff1a;Zookeeper、Etcd、Kafka等&#xff0c;往往會存在一個 【Leader】 角色&#xff0c;并由該角色負責數據的寫入&#xff0c;這樣設計最主要的原因是什么呢&#xff1f; A. 唯一負責數據寫入的 Leader 角色可以避免并…

使用YoloV5和Mediapipe實現——上課玩手機檢測(附完整源碼)

目錄 效果展示 應用場景舉例 1. 課堂或考試監控&#xff08;看到這個學生黨還會愛我嗎&#xff09; 2. 駕駛安全監控&#xff08;防止開車玩手機&#xff09; 3. 企業辦公管理&#xff08;防止工作時間玩手機&#xff09; 4. 監獄、戒毒所、特殊場所安保 5. 家長監管&am…

GPT-4o從語義分割到深度圖生成,大模型狂潮下的計算機視覺:技術進步≠替代危機

隨著上周&#xff0c;GPT-4o原生多模態圖像生成功能的推出&#xff0c;更多玩法也被開發出來。一夜之間&#xff0c;GPT-4o原生多模態能力的釋放&#xff0c;讓圖像生成、語義分割、深度圖構建這些曾需要專業工具鏈支持的復雜任務&#xff0c;變成了普通人輸入一句話就能實現的…

Pytorch 張量操作

在深度學習中&#xff0c;數據的表示和處理是至關重要的。PyTorch 作為一個強大的深度學習框架&#xff0c;其核心數據結構是張量&#xff08;Tensor&#xff09;。張量是一個多維數組&#xff0c;類似于 NumPy 的數組&#xff0c;但具有更強大的功能&#xff0c;尤其是在 GPU …

小程序中跨頁面組件共享數據的實現方法與對比

小程序中跨頁面/組件共享數據的實現方法與對比 在小程序開發中&#xff0c;實現不同頁面或組件之間的數據共享是常見需求。以下是幾種主要實現方式的詳細總結與對比分析&#xff1a; 一、常用數據共享方法 全局變量&#xff08;getApp()&#xff09;、本地緩存&#xff08;w…

vue中的 拖拽

拖拽總結 實現方式特點適用場景HTML5 原生拖拽 API? 直接使用 dataTransfer 進行數據傳輸 ? 兼容性好&#xff08;大部分瀏覽器支持&#xff09; ? 適合簡單的拖拽場景低代碼平臺、表單生成器、組件拖拽Vue/React 組件庫&#xff08;如 Vue Draggable、SortableJS&#xff…

MySQL 函數(入門版)

目錄 一、字符串函數 1、常用的字符串函數 2、函數演示 3、具體案例 二、數值函數 1、常用的數值函數 2、函數演示 3、具體案例 三、日期函數 1、常用的日期函數 2、函數演示 3、具體案例 四、流程函數 1、常用的流程函數 2、函數演示 3、具體案例 在MySQL中&a…

基于快速開發平臺與智能手表的區域心電監測與AI預警系統(源碼+論文+部署講解等)

需要源代碼&#xff0c;演示視頻&#xff0c;ppt設計原稿資料&#xff0c;請文末卡片聯系 !](https://i-blog.csdnimg.cn/direct/242d53cd069940b5b7a6db2bb031d406.png#pic_center)

【神經網絡】python實現神經網絡(三)——正向學習的模擬演練

有了之前的經驗(【神經網絡】python實現神經網絡(二)——正向推理的模擬演練),我們繼續來介紹如何正向訓練神經網絡中的超參(包含權重以及偏置),本章大致的流程圖如下: 一.損失函數 神經網絡以某個指標為基準尋求最優權重參數,而這個指標即可稱之為 “損失函數” 。(…

分區格式變RAW故障深度解析與數據恢復實戰指南?

分區格式變RAW的本質? 當存儲設備&#xff08;如硬盤、U盤或移動硬盤&#xff09;的分區突然顯示為RAW格式時&#xff0c;意味著操作系統無法識別其原有的文件系統結構&#xff08;如NTFS、FAT32等&#xff09;。此時&#xff0c;用戶訪問該分區會提示“需要格式化”或直接顯示…

【QT】Qt5 QtWebEngine使用教程

目錄 1、QtWebEngine相比于QtWebKit的優勢2、項目配置2.1 確認 Qt 版本2.2 在.pro 文件中添加依賴3、顯示網頁4、實現Qt和網頁JavaScript之間的交互4.1 Qt執行網頁的JavaScript代碼4.2 JavaScript調用Qt對象的函數QtWebEngine 是 Qt 框架中用于在應用程序中嵌入 Web 內容的模塊…

網絡安全-等級保護(等保) 1-0 等級保護制度公安部前期發文總結

################################################################################ 等級保護從1994年開始已經有相關文件下發&#xff0c;進行建設&#xff0c;后續今年多年制度完善&#xff0c;現在已進入等保2.0時代&#xff0c;相關政策已運行多年。 前期等保相關發文&…

視圖函數的應用

1.實現將當前日期和時間編碼為HTML文檔并返回的簡單視圖函數 文章目錄 1.實現將當前日期和時間編碼為HTML文檔并返回的簡單視圖函數1.1打開visualcode 按圖示點擊 創建新的終端1.2然后定義ViewDjango項目根目錄下的路由文件urls.py&#xff0c;實現到SimpleView應用的路由路徑1…