日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

003java面试笔记——【java基础篇】从团八百失败面试总结的java面试题(未完待续)

發布時間:2023/12/18 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 003java面试笔记——【java基础篇】从团八百失败面试总结的java面试题(未完待续) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

? ? ?8、java 線程

? ? 1)線程概念,線程與進程

? ? ?線程:線程是“進程”中某個單一順序的控制流。也被稱為輕量進程。線程是進程中的實體,一個進程可以擁有多個線程,一個線程必須有一個父進程。線程不擁有系統資源,只有運行必須的一些數據結構;它與父進程的其它線程共享該進程所擁有的全部資源。進程可以創建和撤消線程,從而實現程序的并發執行。

? ? 進程:進程是操作系統結構的基礎;是一個正在執行的程序;計算機中正在運行的程序實例;可以分配給處理器并由處理器執行的一個實體;由單一順序的執行顯示,一個當前狀態和一組相關的系統資源所描述的活動單元。

? ??線程與進程有時候,線程也稱作輕量級進程。就象進程一樣,線程在程序中是獨立的、并發的執行路徑,每個線程有它自己的堆棧、自己的程序計數器和自己的局部變量。但是,與分隔的進程相比,進程中的線程之間的隔離程度要小。它們共享內存、文件句柄和其它每個進程應有的狀態。進程可以支持多個線程,它們看似同時執行,但互相之間并不同步。一個進程中的多個線程共享相同的內存地址空間,這就意味著它們可以訪問相同的變量和對象,而且它們從同一堆中分配對象。進程是資源分配的基本單位。所有與該進程有關的資源,都被記錄在進程控制塊PCB中。以表示該進程擁有這些資源或正在使用它們。另外,進程也是搶占處理機的調度單位,它擁有一個完整的虛擬地址空間。與進程相對應,線程與資源分配無關它屬于某一個進程,并與進程內的其他線程一起共享進程的資源。當進程發生調度時,不同的進程擁有不同的虛擬地址空間,而同一進程內的不同線程共享同一地址空間線程只由相關堆棧(系統棧或用戶棧)寄存器和線程控制表TCB組成。寄存器可被用來存儲線程內的局部變量,但不能存儲其他線程的相關變量。發生進程切換與發生線程切換時相比較,進程切換時涉及到有關資源指針的保存以及地址空間的變化等問題;線程切換時,由于同不進程內的線程共享資源和地址空間,將不涉及資源信息的保存和地址變化問題,從而減少了操作系統的開銷時間。而且,進程的調度與切換都是由操作系統內核完成,而線程則既可由操作系統內核完成,也可由用戶程序進行。


? ?守護線程在Java中有兩類線程:User Thread(用戶線程)、Daemon Thread(守護線程)?
? ? Daemon的作用是為其他線程的運行提供便利服務,比如垃圾回收線程就是一個很稱職的守護者。User和Daemon兩者幾乎沒有區別,唯一的不同之處就在于虛擬機的離開:如果 User Thread已經全部退出運行了,只剩下Daemon Thread存在了,虛擬機也就退出了。 因為沒有了被守護者,Daemon也就沒有工作可做了,也就沒有繼續運行程序的必要了。?
? ? 值得一提的是,守護線程并非只有虛擬機內部提供,用戶在編寫程序時也可以自己設置守護線程。下面的方法就是用來設置守護線程的。?
? ? public final void setDaemon(boolean on)?

? ??2)線程的生命周期

? ? 派生:線程在進程內派生出來,它即可由進程派生,也可由線程派生。
? ? 阻塞(Block):如果一個線程在執行過程中需要等待某個事件發生,則被阻塞。
? ? 激活(unblock):如果阻塞線程的事件發生,則該線程被激活并進入就緒隊列。
? ? 調度(schedule):選擇一個就緒線程進入執行狀態。
? ? 結束(Finish):如果一個線程執行結束,它的寄存器上下文以及堆棧內容等將被釋放。


? ??3)線程同步與死鎖

? ? ?同步:許多線程在執行中必須考慮與其他線程之間共享數據或協調執行狀態。這就需要同步機制。在Java中每個對象都有一把鎖與之對應。但Java不提供單獨的lock和unlock操作。它由高層的結構隱式實現, 來保證操作的對應。(然而,我們注意到Java虛擬機提供單獨的monito renter和monitorexit指令來實現lock和unlock操作。)?

synchronized語句計算一個對象引用,試圖對該對象完成鎖操作, 并且在完成鎖操作前停止處理。當鎖操作完成synchronized語句體得到執行。當語句體執行完畢(無論正常或異常),解鎖操作自動完成。作為面向對象的語言,synchronized經常與方法連用。一種比較好的辦法是,如果某個變量由一個線程賦值并由別的線程引用或賦值,那么所有對該變量的訪問都必須在某個synchromized語句或synchronized方法內。

? ?死鎖是指兩個或兩個以上的進程在執行過程中,因爭奪資源而造成的一種互相等待的現象,若無外力作用,它們都將無法推進下去。如果程序中有幾個競爭資源的并發線程,那么保證均衡是很重要的。系統均衡是指每個線程在執行過程中都能充分訪問有限的資源。系統中沒有餓死和死鎖的線程。Java并不提供對死鎖的檢測機制。對大多數的Java程序員來說防止死鎖是一種較好的選擇。最簡單的防止死鎖的方法是對競爭的資源引入序號,如果一個線程需要幾個資源,那么它必須先得到小序號的資源,再申請大序號的資源。

? ??4)java線程創建與啟動

? ? ?兩種方式創建線程:擴展java.lang.Thread類、實現java.lang.Runnable接口。

? ? 啟動線程:在線程的Thread對象上調用start()方法,而不是run()或者別的方法。在調用start()方法之前:線程處于新狀態中,新狀態指有一個Thread對象,但還沒有一個真正的線程。在調用start()方法之后:發生了一系列復雜的事情:啟動新的執行線程(具有新的調用棧);該線程從新狀態轉移到可運行狀態;當該線程獲得機會執行時,其目標run()方法將運行。

? ? 線程的名字:一個運行中的線程總是有名字的,名字有兩個來源,一個是虛擬機自己給的名字,一個是你自己的定的名字。在沒有指定線程名字的情況下,虛擬機總會為線程指定名字,并且主線程的名字總是main,非主線程的名字不確定。線程都可以設置名字,也可以通過Thread.currentThread()獲取線程的名字。

? ??5)java的優先級

? ??線程的優先級仍然無法保障線程的執行次序。只不過,優先級高的線程獲取CPU資源的概率較大,優先級低的并非沒機會執行。線程的優先級用1-10之間的整數表示,數值越大優先級越高,默認的優先級為5。在一個線程中開啟另外一個新線程,則新開線程稱為該線程的子線程,子線程初始優先級與父線程相同。

Thread t1 = new MyThread1(); Thread t2 = new Thread(new MyRunnable()); t1.setPriority(10); t2.setPriority(1); ? ?6) wait(),sleep(),yield(),join(),notify(),notifyAll()

? ? wait():是Object 類的方法,對此對象調用wait 方法導致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對象發出notify 方法(或notifyAll)后本線程才進入對象鎖定池準備獲得對象鎖進入運行狀態。?
? ? ?sleep():Thread類的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時后會自動恢復。調用sleep()?不會釋放對象鎖
? ? ?yield():方法只是把線程的狀態有執行狀態打回準備就緒狀態,所以,執行這個方法后,有可能馬上又開始運行,有可能等待很長時間,yield()方法只能讓同優先級的線程有執行的機會,調用yield()不會釋放對象鎖。?yield()方法先檢測當前是否有相同優先級的線程處于同可運行狀態,如有,則把 CPU 的占有權交給此線程,否則繼續運行原來的線程。所以yield()方法稱為“退讓”,它把運行機會讓給了同等優先級的其他線程。

? ??join():?join()方法使調用該方法的線程在此之前執行完畢,也就是等待調用該方法的線程執行完畢后再往下繼續執行。?join() 方法主要是讓調用該方法的thread完成run方法里面的東西后, 在執行join()方法后面的代碼。

? ??t.join():表示當前線程停止執行直到t線程運行完畢;
? ? t.join(1000): 表示當前線程等待t線程運行1000后執行;

? ?notify()/notifyAll():notify和notifyAll都是把某個對象上休息區內的線程喚醒,notify只能喚醒一個,但究竟是哪一個不能確定,而notifyAll則喚醒這個對象上的休息室中所有的線程。

? ? 7)volatile關鍵字

? ??用volatile修飾的變量,線程在每次使用變量的時候,都會讀取變量修改后的最的值。volatile很容易被誤用,用來進行原子性操作。

? ?Java 語言中的 volatile 變量可以被看作是一種 “程度較輕的 synchronized”;與 synchronized 塊相比,volatile 變量所需的編碼較少,并且運行時開銷也較少,但是它所能實現的功能也僅是 synchronized 的一部分。鎖提供了兩種主要特性:互斥(mutual exclusion) 和可見性(visibility)。互斥即一次只允許一個線程持有某個特定的鎖,因此可使用該特性實現對共享數據的協調訪問協議,這樣,一次就只有一個線程能夠使用該共享數據。可見性必須確保釋放鎖之前對共享數據做出的更改對于隨后獲得該鎖的另一個線程是可見的,如果沒有同步機制提供的這種可見性保證,線程看到的共享變量可能是修改前的值或不一致的值,這將引發許多嚴重問題。Volatile 變量具有 synchronized 的可見性特性,但是不具備原子特性。這就是說線程能夠自動發現 volatile 變量的最新值。
? ? 要使 volatile 變量提供理想的線程安全,必須同時滿足下面兩個條件:對變量的寫操作不依賴于當前值;該變量沒有包含在具有其他變量的不變式中。
? ? 第一個條件的限制使 volatile 變量不能用作線程安全計數器。雖然增量操作(x++)看上去類似一個單獨操作,實際上它是一個由讀取-修改-寫入操作序列組成的組合操作,必須以原子方式執行,而 volatile 不能提供必須的原子特性。實現正確的操作需要使 x 的值在操作期間保持不變,而 volatile 變量無法實現這點

? ??每一個線程運行時都有一個線程棧,線程棧保存了線程運行時候變量值信息。當線程訪問某一個對象時候值的時候,首先通過對象的引用找到對應在堆內存的變量的值,然后把堆內存變量的具體值load到線程本地內存中,建立一個變量副本,之后線程就不再和對象在堆內存變量值有任何關系,而是直接修改副本變量的值,在修改完之后的某一個時刻(線程退出之前),自動把線程變量副本的值回寫到對象在堆中變量。這樣在堆中的對象的值就產生變化了。

? ? ?

? ??read and load 從主存復制變量到當前工作內存
? ? use and assign ?執行代碼,改變共享變量值?
? ? store and write 用工作內存數據刷新主存相關內容
? ?其中use and assign 可以多次出現,但是這一些操作并不是原子性,也就是 在read load之后,如果主內存count變量發生修改之后,線程工作內存中的值由于已經加載,不會產生對應的變化,所以計算出來的結果會和預期不一樣。


總結

以上是生活随笔為你收集整理的003java面试笔记——【java基础篇】从团八百失败面试总结的java面试题(未完待续)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。