【java面試】線程篇

【java面試】線程篇

  • 一、基礎知識
    • 1 線程與進程的區別
    • 2 并行與并發的區別
    • 3 創建線程的方式
    • 4 線程包含了哪些狀態,狀態之間是如何變化的?
    • 5 新建三個線程,如何保證他們按照順序執行?
    • 6、java中的wait和sleep方法的不同
    • 7 如何停止一個正在運行的線程
  • 二、線程并發安全
    • 1 synchronized關鍵字的底層原理
      • 1.1 synchronized關鍵字的使用
      • 1.2 Monitor
      • 1.3 總結
    • 2 synchronized關鍵字的底層原理--進階
      • 1.1 Monitor重量級鎖
      • 1.2 輕量級鎖
      • 1.3 偏向鎖
      • 1.4 總結
    • 3 JMM(java memory Model--Java內存模型)
    • 4 CAS
      • 4.1 基本概念
      • 4.2 底層實現
      • 4.3 樂觀鎖和悲觀鎖
      • 4.4 總結
    • 4 volatile
      • 4.1 保證線程間的可見性
      • 4.2 volatile禁止指令重排序
      • 4.3 總結
    • 5 AQS
      • 5.1 基本概念
      • 5.2 基本工作機制
      • 5.3 總結
    • 5 ReentrantLock實現原理
    • 7 synchronized與Lock有什么區別?
    • 8 死鎖產生的條件
      • 8.1 基本概念
      • 8.2 死鎖診斷
    • 9 ConcurrentHashMap
    • 10 導致并發程序出現問題的根本原因
  • 三、線程池
    • 1 線程池的核心參數
      • 1.1 核心參數
      • 1.2 執行原理
    • 2 線程池中常見阻塞隊列
    • 3 如何確定核心線程數
    • 4 線程池種類
    • 5 為什么不建議Executor創建線程池
  • 四、使用場景
    • 1 線程池使用場景
    • 2 es數據批量導入
    • 3 數據匯總
    • 4 異步調用
    • 5 如何控制某個方法允許并發訪問的數量
    • 6 談談對TreadLocal的理解
      • 6.1 set方法
      • 6.2 get方法/remove方法
      • 6.3 ThreadLoca內存泄漏問題

在這里插入圖片描述

一、基礎知識

1 線程與進程的區別

①進程
程序由指令數據組成,但這些指令要運行,數據要讀寫,就必須將指令加載至CPU,數據加載至內存。在指令運行過程中還需要用到磁盤、網絡等設備。進程就是用來加載指令、管理內存、管理IO的
當一個程序被運行,從磁盤加載這個程序的代碼至內存,這時就開啟了一個進程
在這里插入圖片描述

②線程
一個線程就是一個指令流,將指令流中的一條條指令以一定的順序交給CPU 執行,一個進程之內可以分為一到多個線程。
在這里插入圖片描述
③二者區別

  • 進程是正在運行程序的實例,進程中包含了線程,每個線程執行不同的任務
  • 不同的進程使用不同的內存空間,在當前進程下的所有線程可以共享內存空間
  • 線程更輕量,線程上下文切換成本一般上要比進程上下文切換低(上下文切換指的是從一個線程切換到另一個線程)

2 并行與并發的區別

在這里插入圖片描述
在這里插入圖片描述

  • 并發(concurrent)是同一時間應對(dealing with)多件事情的能力
  • 并行(parallel)是同一時間動手做(doing)多件事情的能力

在這里插入圖片描述

3 創建線程的方式

①繼承Thread類
在這里插入圖片描述

②實現runable接口
在這里插入圖片描述

③實現Callable接口(適用于有返回值的)
在這里插入圖片描述

④線程池創建線程
在這里插入圖片描述

開啟線程的方法?

  • 繼承Thread類
  • 實現runnable接口
  • 實現Callable接口
  • 線程池創建線程(項目中使用方式)

使用tunable和callable都可以創建線程,它們之間有什么區別?

  • Runnable接口run方法沒有返回值
  • Callable接口call方法有返回值,是個泛型,和Future、FutureTask配合可以用來獲取異步執行的結果
  • Callable接口的call()方法允許拋出異常;而Runnable接口的run()方法的異常只能在內部消化,不能繼續上拋

在啟動線程時可以使用run方法嗎?run()和start()有什么區別?

  • start():用來啟動線程,通過該線程調用run方法執行run方法中所定義的邏輯代碼。start方法只能被調用一次。(線程只能被開啟一次)
  • run():封裝了要被線程執行的代碼,可以被調用多次。

4 線程包含了哪些狀態,狀態之間是如何變化的?

線程之間包含了那些狀態?
新建(NEW) 、可運行(RUNNABLE)、阻塞(BLOCKED)、等待( WAITING )、時間等待(TIMED_WALTING)、終止(TERMINATED)

在這里插入圖片描述

狀態之間如何轉換?

在這里插入圖片描述

在這里插入圖片描述

5 新建三個線程,如何保證他們按照順序執行?

join{}:等待線程結束

例如:t.join(),阻塞調用次方的的線程進入time_waiting,直到線程t完成后,此線程在繼續執行。

在這里插入圖片描述

notify()和notifyAll()有什么區別?

  • notifyAll():喚醒所有wait的線程
  • notify():只隨機喚醒一個wait線程

6、java中的wait和sleep方法的不同

在這里插入圖片描述

7 如何停止一個正在運行的線程

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

二、線程并發安全

1 synchronized關鍵字的底層原理

1.1 synchronized關鍵字的使用

Synchronized【對象鎖】采用互斥的方式讓同一時刻至多只有一個線程能持有【對象鎖】,其它線程再想獲取這個【對象鎖】時就會阻塞住

在這里插入圖片描述

未加鎖:出現超賣的情況
在這里插入圖片描述
加鎖后:一個線程在扣票的過程中,另一個線程是無法去獲取的
在這里插入圖片描述

1.2 Monitor

在這里插入圖片描述

在這里插入圖片描述

  • Owner:存儲當前獲取鎖的線程的,只能有一個線程可以獲取
  • EntryList:關聯沒有搶到鎖的線程,處于Blocked狀態的線程
  • WaitSet:關聯調用了wait方法的線程,處于Waiting狀態的線程

1.3 總結

  • Synchronized【對象鎖】采用互斥的方式讓同一時刻至多只有一個線程能持有【對象鎖】
  • 它的底層由monitor實現的,monitor是jvm級別的對象(C++實現),線程獲得鎖需要使用對象(鎖)關聯monitor
  • 在monitor內部有三個屬性,分別是owner、entrylist、waitset
  • 其中owner是關聯的獲得鎖的線程,并且只能關聯一個線程;entrylist關聯的是處于阻塞狀態的線程; waitset關聯的是處于Waiting狀態的線程

2 synchronized關鍵字的底層原理–進階

Monitor實現的鎖屬于重量級鎖,你了解過鎖升級碼?

  • Monitor實現的鎖屬于重量級鎖,里面涉及到了用戶態和內核態的切換、進程的上下文切換,成本較高,性能比較低.
  • 在JDK 1.6引入了兩種新型鎖機制:偏向鎖和輕量級鎖,它們的引入是為了解決在沒有多線程競爭或基本沒有競爭的場景下因使用傳統鎖機制帶來的性能開銷問題。

1.1 Monitor重量級鎖

lock對象鎖是怎么關聯上Monitor的?
每個Java對象都可以關聯一個Monitor對象,如果使用synchronized給對象上鎖(重量級)之后,該對象頭的Mark Word 中就被設置指向Monitor對象的指針

通過java對象的內存結構來說明:

MarkWord
在這里插入圖片描述

1.2 輕量級鎖

在很多的情況下,在Java程序運行時,同步塊中的代碼都是不存在競爭的,不同的線程交替的執行同步塊中的代碼。這種情況下,用重量級鎖是沒必要的。因此JVM引入了輕量級鎖的概念。
在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述

1.3 偏向鎖

輕量級鎖在沒有競爭時(就自己這個線程),每次重入仍然需要執行CAS操作。Java 6中引入了偏向鎖來做進一步優化:只有第一次使用CAS將線程ID設置到對象的Mark Word頭,之后發現這個線程ID是自己的就表示沒有競爭,不用重新CAS。以以后只要不發生競爭,這個對象就歸該線程所有
在這里插入圖片描述

1.4 總結

Java中的synchronized有偏向鎖、輕量級鎖、重量級鎖三種形式,分別對應了鎖只被一個線程持有、不同線程交替持有鎖、多線程競爭鎖三種情況。
在這里插入圖片描述
一旦鎖發生了競爭都會升級為重量級鎖

3 JMM(java memory Model–Java內存模型)

JMM(Java Memory Model)Java內存模型,定義了共享內多線程程序讀寫操作的行為規范,通過這些規則來規范對內存的讀寫操作從而保證指令的正確性

在這里插入圖片描述

  • JMM(Java Memory Model)Java內存模型,定義了共享內存中多線程程序讀寫操作的行為規范,通過這些規則來規范對內存的讀寫操作從而保證指令的正確性
  • JMM把內存分為兩塊,一塊是私有線程的工作區域(工作內存),一塊是所有線程的共享區域(主內存)
  • 線程跟線程之間是相互隔離,線程跟線程交互需要通過主內存

4 CAS

4.1 基本概念

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
比對失敗,重新讀一份V到線程B的A中,設置閾值,多少次之后還沒修改成功,就放棄修改。

4.2 底層實現

CAS 底層依賴于一個Unsafe類來直接調用操作系統底層的cAs指令
native修飾的本地方法,是系統提供的,不是java提供的,是由C或者C++實現的。
在這里插入圖片描述

在這里插入圖片描述

4.3 樂觀鎖和悲觀鎖

CAS是基于樂觀鎖的思想:最樂觀的估計,不怕別的線程來修改共享變量,就算改了也沒關系,我吃虧點再重試唄。
synchronized是基于悲觀鎖的思想:最悲觀的估計,得防著其它線程來修改共享變量,我上了鎖你們都別想改,我改完了解開鎖,你們才有機會。

4.4 總結

在這里插入圖片描述

4 volatile

請談談對volatile的理解?
volatile是一個關鍵字,一旦一個共享變量(類的成員變量、類的靜態成員變量)被volatile修飾之后,那么就具備了兩層語義:
①保證線程間的可見性
②禁止進行指令重排序

4.1 保證線程間的可見性

在這里插入圖片描述
在這里插入圖片描述在這里插入圖片描述
在這里插入圖片描述

4.2 volatile禁止指令重排序

在這里插入圖片描述
測試:
a.引入依賴
在這里插入圖片描述
b.加注解
在這里插入圖片描述
c.沒有main方法無法執行,自己指定
在這里插入圖片描述

在這里插入圖片描述

d.查看執行結果
在這里插入圖片描述

在這里插入圖片描述
y上加volatile關鍵字運行結果:在X上不行。
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

4.3 總結

在這里插入圖片描述

5 AQS

5.1 基本概念

在這里插入圖片描述

5.2 基本工作機制

在這里插入圖片描述

多個線程爭搶資源如何保證原子性?

在這里插入圖片描述
在這里插入圖片描述

AQS是公平鎖還是非公平鎖?
既可以實現公平鎖也可以實現非公平鎖。

線程1釋放鎖之后,新來的線程5和等待隊列的隊首線程競爭鎖
在這里插入圖片描述
新的線程與隊列中的線程共同來搶資源,是非公平鎖
新的線程到隊列中等待,只讓隊列中的head線程獲取鎖,是公平鎖

5.3 總結

在這里插入圖片描述

5 ReentrantLock實現原理

ReentrantLock翻譯過來是可重入鎖,相對于synchronized它具備以下特點:

  • 可中斷:
  • 可以設置超時時間:超過時間沒有獲取到鎖可以放棄獲取鎖
  • 可以設置公平鎖
  • 支持多個條件變量:可以設置多個條件讓線程進入等待狀態
  • 與synchronized一樣,都支持重入


在這里插入圖片描述
在這里插入圖片描述
總結:
在這里插入圖片描述

7 synchronized與Lock有什么區別?

在這里插入圖片描述

8 死鎖產生的條件

8.1 基本概念

在這里插入圖片描述

8.2 死鎖診斷

在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

9 ConcurrentHashMap

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

在這里插入圖片描述

在這里插入圖片描述

10 導致并發程序出現問題的根本原因

導致并發程序出現問題的根本原因
(或者說:java程序中怎么保證多線程的執行安全)

java并發編程的三大特性:

  • 原子性
  • 可見性
  • 有序性

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

三、線程池

1 線程池的核心參數

說一下線程池的核心參數
(線程池的執行原理知道嗎)

1.1 核心參數

在這里插入圖片描述

1.2 執行原理

在這里插入圖片描述

2 線程池中常見阻塞隊列

在這里插入圖片描述
在這里插入圖片描述

3 如何確定核心線程數

在這里插入圖片描述
在這里插入圖片描述

4 線程池種類

在這里插入圖片描述

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

5 為什么不建議Executor創建線程池

在這里插入圖片描述

四、使用場景

1 線程池使用場景

線程池使用場景(CountDownLatch、future)
你做過的項目中哪里用到了多線程

在這里插入圖片描述

2 es數據批量導入

在這里插入圖片描述

在這里插入圖片描述

3 數據匯總

在這里插入圖片描述
在這里插入圖片描述

4 異步調用

保存搜索記錄,不能影響當前搜索的搜索結果。
在這里插入圖片描述
在這里插入圖片描述

5 如何控制某個方法允許并發訪問的數量

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

6 談談對TreadLocal的理解

在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

6.1 set方法

在這里插入圖片描述

6.2 get方法/remove方法

在這里插入圖片描述

6.3 ThreadLoca內存泄漏問題

java對象中四種引用類型:強引用、軟引用、弱引用、虛引用
在這里插入圖片描述
在這里插入圖片描述
在這里插入圖片描述

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

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

相關文章

RAGFlow是一個基于深度文檔理解的開源RAG引擎

RAGFlow概述 RAGFlow是一款基于深度文檔理解的開源RAG(檢索增強生成)引擎,專注于處理復雜文檔結構并提供精準的語義檢索與生成能力。其核心優勢在于結合多模態文檔解析和智能分段技術,優化傳統RAG流程中的信息提取與答案生成效果…

Git Commit 模板完整配置指南

Git Commit 模板完整配置指南 📋 目錄 Git Commit 模板完整配置指南 📋 目錄🎯 為什么需要 Commit 模板📝 推薦的 Commit 模板 標準模板格式C 項目特化模板 ?? 系統級配置 1. 創建模板文件2. 配置 Git 使用模板3. 驗證配置 &a…

【ELK服務搭建】

Ubuntu 20.04環境下部署Elastic Stack 8.18日志系統完整指南 一、環境準備 系統要求 Ubuntu 20.04 LTS硬件配置:4核CPU / 8GB內存 / 100GB硬盤網絡:需外網訪問權限 1. 基礎環境配置 首先安裝SSH服務以便遠程管理: # 更新軟件源 apt u…

Mac電腦 Office 2024 LTSC 長期支持版(Excel、Word、PPT)

Office 2024 mac,是一款是一款專為蘋果電腦用戶設計的高性能、高安全性的辦公套裝 集成了Word、Excel、PowerPoint、Outlook等經典應用,為用戶提供了一站式的辦公解決方案。 不僅繼承了Office系列一貫的卓越性能,還在功能性和用戶體驗上進行…

深入解析 Schema 在不同數據庫中的百變面孔

在數據庫的世界里,數據是核心資產,但如何高效、有序、安全地組織和理解這些數據?答案就是 Schema(模式或架構)。它如同建筑的圖紙、樂隊的樂譜,是數據庫的設計藍圖和運行規則手冊。今天,我們就來…

Python 數據分析與可視化 Day 2 - 數據清洗基礎

🎯 今日目標 學會識別和處理缺失數據(NaN)學會刪除/填補缺失值清理重復數據修改列類型,準備數據分析 🧼 一、缺失值處理(NaN) ? 1. 檢查缺失值 import pandas as pd df pd.read_csv("…

3DS中文游戲全集下載 任天堂3DS簡介3DS第一方獨占游戲推薦

任天堂3DS 的詳細介紹,涵蓋其硬件特性、核心功能、游戲陣容及歷史地位: 3DS游戲全集下載 https://pan.quark.cn/s/dd40e47387e7 https://sink-698.pages.dev/3ds CIA CCA 等格式可用于3DS模擬器和3DS實體機 3DS 是什么? 全稱:Nin…

【Python小練習】3D散點圖

資產風險收益三維分析 背景 王老師是一名金融工程研究員,需要對多個資產的預期收益、風險(波動率)和與市場的相關性進行綜合分析,以便為投資組合優化提供決策依據。 代碼實現 import matplotlib.pyplot as plt from mpl_toolk…

安寶特案例丨突破傳統手術室,Vuzix AR 眼鏡圓滿助力全膝關節置換術

在巴西圣保羅醫院的手術室里,骨科權威 Ricardo Gobbi醫生正戴著 安寶特 Vuzix 智能 AR 眼鏡,為一位膝關節炎患者實施全膝關節置換術。與傳統手術不同的是,他的視野中實時疊加著骨骼三維模型、切割路徑標線和動態數據 —— 這并非科幻場景&…

qt設置文件自動保存-cnblog

步驟: 「工具」->「選項」->「環境」->「Auto-save modified files」。 可開啟/關閉自動保存文件功能,還可設置自動保存時間的間隔(最短間隔1分鐘)。 鐘)。

linux下如何找到dump文件被生成到哪里了

在大多數 Linux 系統中,核心轉儲文件(core dump)通常由系統自動保存在當前工作目錄下,或者由配置決定其保存位置。核心轉儲文件的默認文件名通常包含進程 ID(PID)和程序名,例如 core.PID 或 cor…

API 調試工具校驗 JSON Mock 接口(一):無參請求與基礎響應驗證

在前后端分離的開發模式中,JSON Mock 工具為前端開發人員在后端接口未就緒時提供了極大便利,能夠模擬返回 JSON 數據的 API 接口,實現前端獨立開發與測試。而 API 開發調試工具 作為一款強大的接口測試工具,可進一步對這些 Mock 接…

單體架構、微服務架構和分布式架構的區別

. 架構定義與核心特征 1.1 單體架構(Monolithic Architecture) 單體架構是將所有功能模塊集中在一個單一代碼庫中的傳統架構模式: 所有功能(UI層、業務邏輯、數據訪問)打包為單一部署單元通常使用單一技術棧開發(如Spring Boot、Django等)共享單一數據庫實例進程內通信(方法…

如何重新安裝 Rust

在開發過程中,我們有時可能需要重新安裝 Rust,比如遇到版本沖突、環境配置錯誤,或者僅僅是想更新到最新版本。本文將詳細介紹如何卸載現有 Rust 安裝,并重新安裝 Rust,同時還會介紹一些常見的配置技巧,幫助…

使用springboot實現過濾敏感詞功能

一,在springboot項目的resources目錄里創建sensitive-words.text(敏感詞文本) 每個詞獨自一行 列如: 賭博 吸毒 開票 二,在util創建工具類SensitiveFilter package com.nowcoder.community.util;Component public c…

Vue 蒼穹外賣

Vue 蒼穹外賣 node_modules:當前項目依賴的js包 assets:靜態資源存放目錄 components:公共組件存放目錄 App.vue:項目的主組件,頁面的入口文件 main.js:整個項目的入口文件 package.json:項…

評估視覺在CNN 在人類動作識別準確率

大家讀完覺得有幫助記得關注和點贊!!! 抽象 本研究使用 COCO 圖像語料庫的三類子集探索人類動作識別,對從簡單的全連接網絡到 transformer 架構的模型進行基準測試。二進制 Vision Transformer (ViT) 實現了…

Self-supervised Learning(BERT/GPT/T5)

李宏毅老師《Pre-train Model》 什么是:Self-supervised Learning BERT BERT 能做什么 Mask Input Next Sentence Prediction(not helpful) BERT其它的能力 上述的能力,可以認為是一種填空的能力,那么除了這些,還有哪些有用的能力呢&…

《NuGet:.NET開發的魔法包管理器》

一、NuGet 初相識 在軟件開發的廣袤天地中,依賴管理始終是一個核心議題。想象一下,在沒有高效包管理工具的年代,開發者如同在黑暗中摸索前行。當項目逐漸龐大,所需的外部庫和組件日益增多,手動管理這些依賴就如同一場噩…

Vulkan 學習筆記12—深度緩沖

一、3D幾何體與深度問題 Z坐標引入 將2D幾何體擴展為3D時,需在Vertex結構體中添加glm::vec3 pos表示三維位置,并更新頂點輸入描述符格式為VK_FORMAT_R32G32B32_SFLOAT。頂點著色器需接收3D坐標并通過模型-視圖-投影矩陣轉換為裁剪坐標。 深度沖突問題 當…