java-多線程

介紹一下Syncronized鎖。如果用這個(gè)關(guān)鍵字修飾一個(gè)靜態(tài)方法,鎖住了什么?如果修飾成員方法,鎖住了什么?

修飾靜態(tài)方法、修飾成員變量:相當(dāng)于全局鎖,相當(dāng)于鎖住了整個(gè)類。

synchronized(this)以及非static的synchronized方法(至于static synchronized方法請(qǐng)往下看),只能防止多個(gè)線程同時(shí)執(zhí)行同一個(gè)對(duì)象的同步代碼段

介紹一下volatile

保證可見性,有序性

當(dāng)把變量聲明為volatile類型后,編譯器與運(yùn)行時(shí)都會(huì)注意到這個(gè)變量是共享的,因此不會(huì)將該變量上的操作與其他內(nèi)存操作一起重排序。volatile變量不會(huì)被緩存在寄存器或者對(duì)其他處理器不可見的地方,因此在讀取volatile類型的變量時(shí)總會(huì)返回最新寫入的值。

在訪問volatile變量時(shí)不會(huì)執(zhí)行加鎖操作,因此也就不會(huì)使執(zhí)行線程阻塞,因此volatile變量是一種比sychronized關(guān)鍵字更輕量級(jí)的同步機(jī)制。

而聲明變量是 volatile 的,JVM 保證了每次讀變量都從內(nèi)存中讀

lock(防止指令重排序)

在執(zhí)行程序時(shí)為了提高性能,編譯器和處理器通常會(huì)對(duì)指令做重排序:

編譯器重排序。編譯器在不改變單線程程序語(yǔ)義的前提下,可以重新安排語(yǔ)句的執(zhí)行順序;

處理器重排序。如果不存在數(shù)據(jù)依賴性,處理器可以改變語(yǔ)句對(duì)應(yīng)機(jī)器指令的執(zhí)行順序;

多線程中的i++線程安全嗎?為什么?

局部變量中安全,全局變量不安全。

i++不是原子性操作,相當(dāng)于int tp1 = i; int tp2 = tp1+1; i = tp2;?

如何線程安全的實(shí)現(xiàn)一個(gè)計(jì)數(shù)器?

使用AtomicInteger 等原子類。

給i++加鎖

線程同步有哪幾種方式

1.同步方法

2.同步代碼塊??

3.使用特殊域變量(volatile)實(shí)現(xiàn)線程同步

4.使用重入鎖實(shí)現(xiàn)線程同步?

5.使用局部變量實(shí)現(xiàn)線程同步 (使用ThreadLocal管理變量)

6.wait與notify

7.使用原子變量實(shí)現(xiàn)線程同步

concurrenthashmap有啥優(yōu)勢(shì),1.7,1.8區(qū)別

http://www.importnew.com/23610.html

AQS(AbstractQueuedSynchronized)

Java并發(fā)之AQS詳解 - CodesGeek - 博客園

CAS(Compare And Swap?)

如果V值等于E值,則將V的值設(shè)為N。若V值和E值不同,則說明已經(jīng)有其他線程做了更新,則當(dāng)前線程什么都不做。

通俗的理解就是CAS操作需要我們提供一個(gè)期望值,當(dāng)期望值與當(dāng)前線程的變量值相同時(shí),說明還沒線程修改該值,當(dāng)前線程可以進(jìn)行修改,也就是執(zhí)行CAS操作,但如果期望值與當(dāng)前線程不符,則說明該值已被其他線程修改,此時(shí)不執(zhí)行更新操作,但可以選擇重新讀取該變量再嘗試再次修改該變量,也可以放棄操作

ABA

比如說一個(gè)線程one從內(nèi)存位置V中取出A,這時(shí)候另一個(gè)線程two也從內(nèi)存中取出A,并且two進(jìn)行了一些操作變成了B,然后two又將V位置的數(shù)據(jù)變成A,這時(shí)候線程one進(jìn)行CAS操作發(fā)現(xiàn)內(nèi)存中仍然是A,然后one操作成功。盡管線程one的CAS操作成功,但是不代表這個(gè)過程就是沒有問題的。如果鏈表的頭在變化了兩次后恢復(fù)了原值,但是不代表鏈表就沒有變化。因此前面提到的原子操作。

各種樂觀鎖的實(shí)現(xiàn)中通常都會(huì)用版本戳version來對(duì)記錄或?qū)ο髽?biāo)記,避免并發(fā)操作帶來的問題。

線程安全的Map都有啥,Collections.synchronizedmap(),ConcurrentHashMap,Hashtable 底層實(shí)現(xiàn)

線程池運(yùn)行流程,參數(shù),策略

線程池相關(guān)筆記,線程池的實(shí)現(xiàn)?四種線程池?重要參數(shù)及原理?任務(wù)拒接策略有哪幾種? - CSDN博客

synchronized,偏向鎖,輕量級(jí)鎖,重量級(jí)鎖,鎖膨脹機(jī)制

Synchronized的原理及自旋鎖,偏向鎖,輕量級(jí)鎖,重量級(jí)鎖的區(qū)別 - CSDN博客

wait方法底層原理?join,notify,notifyall

多線程(二):詳細(xì)描述wait、notify/notifyAll、join及底層實(shí)現(xiàn) - CSDN博客

線程池原理

理解線程池的原理 - CSDN博客

講一下非公平鎖和公平鎖在reetrantlock里的實(shí)現(xiàn)。

FairSync 公平鎖?

公平鎖就是每個(gè)線程在獲取鎖時(shí)會(huì)先查看此鎖維護(hù)的等待隊(duì)列,如果為空,或者當(dāng)前線程線程是等待隊(duì)列的第一個(gè),就占有鎖,否則就會(huì)加入到等待隊(duì)列中,以后會(huì)按照FIFO的規(guī)則從隊(duì)列中獲取,

講一下synchronized,可重入怎么實(shí)現(xiàn)

Java中一個(gè)線程在通過synchronized獲取到一個(gè)對(duì)象的對(duì)象鎖后會(huì)阻塞試圖獲取該對(duì)象鎖的其他線程,但不會(huì)阻塞當(dāng)前線程,也就是說synchronized代碼塊對(duì)當(dāng)前線程來說是可重入的

多線程實(shí)現(xiàn)方法

繼承Thread類創(chuàng)建線程類,重寫run方法,run方法就是代表線程需要完成的任務(wù),調(diào)用線程對(duì)象的start()來啟動(dòng)該線程,線程類已經(jīng)繼承了Thread類,所以不能再繼承其他父類。? ?

實(shí)現(xiàn)Runnable接口創(chuàng)建線程類,定義Runnable實(shí)現(xiàn)類,重寫run方法? ?

實(shí)現(xiàn)Callable接口,重寫call()方法,call()作為線程的執(zhí)行體,具有返回值? ?

線程池,使用線程池產(chǎn)生線程對(duì)象java.util.concurrent.ExecutorService、java.util.concurrent.Executors;

Synchronized和lock區(qū)別

Lock提供了synchronized關(guān)鍵字所不具備的主要特性有:

嘗試非阻塞地獲取鎖boolean tryLock():當(dāng)前線程嘗試獲取鎖,如果這一時(shí)刻沒有被其他線程獲取到,則成功獲取并持有鎖? ? ? ?

能被中斷地獲取鎖void lockInterruptibly():當(dāng)獲取到鎖的線程被中斷時(shí),中斷異常拋出同時(shí)會(huì)釋放鎖? ? ? ?

超時(shí)獲取鎖boolean trylock(long time, TimeUnit unit):在指定截止時(shí)間之前獲取鎖,如果在截止時(shí)間仍舊無法獲取鎖,則返回? ? ?

synchronized是JVM提供的加鎖,悲觀鎖;lock是Java語(yǔ)言實(shí)現(xiàn)的,而且是樂觀鎖。? ?

ReentrantLock是基于AQS實(shí)現(xiàn)的,由于AQS是基于FIFO隊(duì)列的實(shí)現(xiàn)

Java中都有什么鎖

重量級(jí)鎖、顯式鎖、并發(fā)容器、并發(fā)同步器、CAS、volatile、AQS等

可重入鎖的設(shè)計(jì)思路是什么

可重入公平鎖獲取流程

在獲取鎖的時(shí)候,如果當(dāng)前線程之前已經(jīng)獲取到了鎖,就會(huì)把state加1,在釋放鎖的時(shí)候會(huì)先減1,這樣就保證了同一個(gè)鎖可以被同一個(gè)線程獲取多次,而不會(huì)出現(xiàn)死鎖的情況。這就是ReentrantLock的可重入性。

對(duì)于非公平鎖而言,調(diào)用lock方法后,會(huì)先嘗試搶占鎖,在各種判斷的時(shí)候會(huì)先忽略等待隊(duì)列,如果鎖可用,就會(huì)直接搶占使用。

樂觀鎖和悲觀鎖

悲觀鎖:假定會(huì)發(fā)生并發(fā)沖突,則屏蔽一切可能違反數(shù)據(jù)完整性的操作

樂觀鎖:假定不會(huì)發(fā)生并發(fā)沖突,只在數(shù)據(jù)提交時(shí)檢查是否違反了數(shù)據(jù)完整性(不能解決臟讀問題)

juc包內(nèi)有哪些類

CountDownLatch 同步計(jì)數(shù)器,主要用于線程間的控制,但計(jì)數(shù)無法被重置,如果需要重置計(jì)數(shù),請(qǐng)考慮使用 CyclicBarrier 。

線程池新任務(wù)到達(dá)時(shí)會(huì)先使用空閑線程還是加入阻塞隊(duì)列

Java并發(fā)包里面的CountdownLatch怎么使用

這個(gè)類是一個(gè)同步計(jì)數(shù)器,主要用于線程間的控制,當(dāng)CountDownLatch的count計(jì)數(shù)>0時(shí),await()會(huì)造成阻塞,直到count變?yōu)?,await()結(jié)束阻塞,使用countDown()會(huì)讓count減1。CountDownLatch的構(gòu)造函數(shù)可以設(shè)置count值,當(dāng)count=1時(shí),它的作用類似于wait()和notify()的作用。如果我想讓其他線程執(zhí)行完指定程序,其他所有程序都執(zhí)行結(jié)束后我再執(zhí)行,這時(shí)可以用CountDownLatch,但計(jì)數(shù)無法被重置,如果需要重置計(jì)數(shù),請(qǐng)考慮使用 CyclicBarrier 。

volatile和synchronized區(qū)別

volatile是變量修飾符,其修飾的變量具有可見性,Java的做法是將該變量的操作放在寄存器或者CPU緩存上進(jìn)行,之后才會(huì)同步到主存,使用volatile修飾符的變量是直接讀寫主存,volatile不保證原子性,同時(shí)volatile禁止指令重排? ?

synchronized作用于一段代碼或者方法,保證可見性,又保證原子性,可見性是synchronized或者Lock能保證通一個(gè)時(shí)刻只有一個(gè)線程獲取鎖然后執(zhí)行不同代碼,并且在釋放鎖之前會(huì)對(duì)變量的修改刷新到主存中去,原子性是指要么不執(zhí)行,要執(zhí)行就執(zhí)行到底

一般線程和守護(hù)線程的區(qū)別

java中的線程分為兩種:守護(hù)線程(Daemon)和用戶線程(User)。

任何線程都可以設(shè)置為守護(hù)線程和用戶線程,通過方法Thread.setDaemon(bool on);true則把該線程設(shè)置為守護(hù)線程,反之則為用戶線程。Thread.setDaemon()必須在Thread.start()之前調(diào)用,否則運(yùn)行時(shí)會(huì)拋出異常。

唯一的區(qū)別是判斷虛擬機(jī)(JVM)何時(shí)離開,Daemon是為其他線程提供服務(wù),如果全部的User Thread已經(jīng)撤離,Daemon 沒有可服務(wù)的線程,JVM撤離。也可以理解為守護(hù)線程是JVM自動(dòng)創(chuàng)建的線程(但不一定),用戶線程是程序創(chuàng)建的線程;比如JVM的垃圾回收線程是一個(gè)守護(hù)線程,當(dāng)所有線程已經(jīng)撤離,不再產(chǎn)生垃圾,守護(hù)線程自然就沒事可干了,當(dāng)垃圾回收線程是Java虛擬機(jī)上僅剩的線程時(shí),Java虛擬機(jī)會(huì)自動(dòng)離開。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 線程同步 在大多數(shù)實(shí)際的多線程應(yīng)用中, 兩個(gè)或兩個(gè)以上的線程需要共享對(duì)同一數(shù)據(jù)的存取。多個(gè)線程或者進(jìn)程在讀寫一個(gè)共...
    Steven1997閱讀 2,046評(píng)論 0 3
  • 本文是我自己在秋招復(fù)習(xí)時(shí)的讀書筆記,整理的知識(shí)點(diǎn),也是為了防止忘記,尊重勞動(dòng)成果,轉(zhuǎn)載注明出處哦!如果你也喜歡,那...
    波波波先森閱讀 11,619評(píng)論 4 56
  • 當(dāng)你從新去走你走過得路的時(shí)候,就像打怪升級(jí)明明馬上就要超神了,卻要一切重新來過,如果不能改寫,活該重蹈覆轍,因?yàn)槟?..
    你滿我滿閱讀 226評(píng)論 0 0
  • 癌的源頭 很多人一聽某某人得了癌癥,就好比上帝宣判了死刑一樣,很多人就會(huì)覺得下一個(gè)估計(jì)就是我要得癌癥。其實(shí)不是,要...
    文藝氣息的工程師閱讀 1,996評(píng)論 6 4
  • 我有一個(gè)壞毛?。嚎吹揭患碌臅r(shí)候,總是不由自主的想要做一個(gè)價(jià)值判斷,是非對(duì)錯(cuò)。這本就已經(jīng)不是什么好習(xí)慣了,但是更糟...
    jianlong3閱讀 153評(píng)論 0 0

友情鏈接更多精彩內(nèi)容