摘要:當兩個并發(fā)線程訪問同一個對象中的這個同步代碼塊時,一個時間內(nèi)只能有一個線程得到執(zhí)行。第三個例子同樣適用其它同步代碼塊。也就是說,當一個線程訪問的一個同步代碼塊時,它就獲得了這個的對象鎖。
概述
春節(jié)的時候去面試了一家公司,筆試題里面有一道是使用簡單的代碼實現(xiàn)線程的‘死鎖’,當時沒有想到這道題考的是Synchronized關(guān)鍵字,于是自己定義了兩個資源模擬了一下。后面想想腸子都悔青了,于是自己在電腦上敲了一遍,同時也是對自己的一個提醒,基礎(chǔ)功夫還不夠扎實。
Synchronized關(guān)鍵字Java語言的關(guān)鍵字,當它用來修飾一個方法或者一個代碼塊的時候,能夠保證在同一時刻最多只有一個線程執(zhí)行該段代碼。
當兩個并發(fā)線程訪問同一個對象object中的這個synchronized(this)同步代碼塊時,一個時間內(nèi)只能有一個線程得到執(zhí)行。另一個線程必須等待當前線程執(zhí)行完這個代碼塊以后才能執(zhí)行該代碼塊。
然而,當一個線程訪問object的一個synchronized(this)同步代碼塊時,另一個線程仍然可以訪問該object中的非synchronized(this)同步代碼塊。
尤其關(guān)鍵的是,當一個線程訪問object的一個synchronized(this)同步代碼塊時,其他線程對object中所有其它synchronized(this)同步代碼塊的訪問將被阻塞。
第三個例子同樣適用其它同步代碼塊。也就是說,當一個線程訪問object的一個synchronized(this)同步代碼塊時,它就獲得了這個object的對象鎖。結(jié)果,其它線程對該object對象所有同步代碼部分的訪問都被暫時阻塞。
以上規(guī)則對其它對象鎖同樣適用.
代碼示例package test160118; public class TestSynchronized { public static void main(String[] args) { Sy sy = new Sy(0); Sy sy2 = new Sy(1); sy.start(); sy2.start(); } } class Sy extends Thread { private int flag ; static Object x1 = new Object(); static Object x2 = new Object(); public Sy(int flag) { this.flag = flag; } @Override public void run() { System.out.println(flag); try { if (flag == 0) { synchronized (x1) { System.out.println(flag+"鎖住了x1"); Thread.sleep(1000); synchronized (x2) { System.out.println(flag+"鎖住了x2"); } System.out.println(flag+"釋放了x1和x2"); } } if(flag == 1) { synchronized (x2) { System.out.println(flag+"鎖住了x2"); Thread.sleep(1000); synchronized (x1) { System.out.println(flag+"鎖住了x1"); } System.out.println(flag+"釋放了x1和x2"); } } } catch (InterruptedException e) { e.printStackTrace(); } } }總結(jié)
總之說多了都是淚,關(guān)鍵不是我不會而是我沒有想到它考的都是這個。也不知道面試過沒過,有點方。后面會陸陸續(xù)續(xù)把之前面試時答得不是很好的幾道題寫成專欄的。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/65489.html
摘要:超詳細的面試題總結(jié)一之基本知識多線程和虛擬機創(chuàng)建線程有幾種不同的方式你喜歡哪一種為什么繼承類實現(xiàn)接口應(yīng)用程序可以使用框架來創(chuàng)建線程池實現(xiàn)接口。死亡線程方法執(zhí)行結(jié)束,或者因異常退出了方法,則該線程結(jié)束生命周期。死亡的線程不可再次復生。 超詳細的Java面試題總結(jié)(一)之Java基本知識 多線程和Java虛擬機 創(chuàng)建線程有幾種不同的方式?你喜歡哪一種?為什么? 繼承Thread類 實現(xiàn)R...
摘要:實現(xiàn)死鎖的方法有兩種,一種是使用同步代碼塊,另一種是使用重入鎖。但是如果調(diào)用帶超時的方法,那么如果線程在等待時被中斷,將拋出一個異常,這是一個非常有用的特性,因為它允許程序打破死鎖。 思路: 死鎖是指在多線程環(huán)境下的這么一種場景,兩個(多個)線程在分別拿到自己的鎖時嘗試獲取對方的鎖,由于必須等待對方釋放鎖才能獲取,然而雙方誰也不肯先釋放自己的鎖, 導致雙方誰都無法繼續(xù)執(zhí)行。通過一個實現(xiàn)...
摘要:相比與其他操作系統(tǒng)包括其他類系統(tǒng)有很多的優(yōu)點,其中有一項就是,其上下文切換和模式切換的時間消耗非常少。因為多線程競爭鎖時會引起上下文切換。減少線程的使用。很多編程語言中都有協(xié)程。所以如何避免死鎖的產(chǎn)生,在我們使用并發(fā)編程時至關(guān)重要。 系列文章傳送門: Java多線程學習(一)Java多線程入門 Java多線程學習(二)synchronized關(guān)鍵字(1) java多線程學習(二)syn...
摘要:因為多線程競爭鎖時會引起上下文切換。減少線程的使用。舉個例子如果說服務(wù)器的帶寬只有,某個資源的下載速度是,系統(tǒng)啟動個線程下載該資源并不會導致下載速度編程,所以在并發(fā)編程時,需要考慮這些資源的限制。 最近私下做一項目,一bug幾日未解決,總惶恐。一日頓悟,bug不可怕,怕的是項目不存在bug,與其懼怕,何不與其剛正面。 系列文章傳送門: Java多線程學習(一)Java多線程入門 Jav...
摘要:例如,張三同時申請賬本和,賬本管理員如果發(fā)現(xiàn)文件架上只有賬本,這個時候賬本管理員是不會把賬本拿下來給張三的,只有賬本和都在的時候才會給張三。但仍需注意的是,有時候預防死鎖成本也是很高的。 在上一篇中,我們嘗試使用了 Account.class作為互斥鎖,來解決轉(zhuǎn)賬問題。但是很容易發(fā)現(xiàn)這樣,所有的轉(zhuǎn)賬操作都是串行的,性能太差了。 讓我們嘗試提升下性能。 向現(xiàn)實世界要答案 現(xiàn)實世界中,轉(zhuǎn)賬...
摘要:如何檢測死鎖由于死鎖極難通過人工的方式查出來,因此提供了命令來檢測某個進程中心線程的情況,并排查有沒有死鎖。線程持有的鎖,等待的鎖。避免出現(xiàn)死鎖,如果出現(xiàn)了死鎖,則可以使用命令查看線程是否有死鎖。 showImg(https://segmentfault.com/img/remote/1460000014936757); 前言 在 Java 的并發(fā)編程中,有一個問題需要特別注意,那就是...
閱讀 2670·2021-11-23 09:51
閱讀 2427·2021-09-30 09:48
閱讀 2057·2021-09-22 15:24
閱讀 1020·2021-09-06 15:02
閱讀 3320·2021-08-17 10:14
閱讀 1951·2021-07-30 18:50
閱讀 1990·2019-08-30 15:53
閱讀 3189·2019-08-29 18:43