JAVA-初步認識-第十三章-多線程(驗證同步函數的鎖)

一.

至于同步函數用的是哪個鎖,我們可以驗證一下,借助原先賣票的例子

?對于程序中的num,從100改為400,DOS的結果顯示的始終都是0線程,票號最小都是1。

票號是沒有問題的,因為同步了。

有人針對只出現0線程,說是票數太少,0線程都給操作完了。即使改成四萬張票,也是0線程操作。

正常來說,四個線程0~3,誰搶到誰就運行。問題出現在哪兒?

程序中run函數是public synchronized void run(),沒有搞清楚什么時候用同步,什么時候不用同步。

我們知道該同步的是if整個語句,

現在我們是從run方法就開始了同步,也就是說在run語句的上面,同時來了四個線程,一個線程在run方法里沒執行完所有的語句,其他線程就無法進來。而run里面就包含著循環售票,也就是說一個線程進到run方法里,售完了票才出去。

看下圖,在if中0線程處于sleep狀態時,1~3號線程得到了執行權,但是進不來。

而且,0線程出不去了,因為while中的判斷始終是正確的。(是不是說,即使循環執行完了,0線程還呆在里面,因為while始終是正確的?)

出現這樣的原因就是不需要將run方法整體同步,只需要將if代碼塊同步,怎么解決呢?

單獨地將if語句定義成函數,將該函數同步,接著調用即可。

DOS結果顯示,四個線程都出來了。(這里show方法可以直接調用,不用創建對象啥的么?)

二. 驗證同步函數的鎖

基于上面的例子,我們來驗證同步函數的鎖是哪一個?

現在為了方便起見,將四個線程減少為兩個線程。兩個線程運行的動作是一樣的,都在賣票。一個是在同步代碼塊里賣票,一個是在同步函數中賣票。(同步函數和同步代碼塊兩者不是一樣么?)

如果這兩個線程用的是同一個鎖的話,就不會出現安全隱患。0線程在同步函數里,1線程在同步代碼塊里,如果它倆用的是同一個鎖,那說明0線程在運行同步函數的時候,1線程不能運行同步代碼塊的,(這是不是說明同步代碼塊和同步函數都是靠鎖來操作的原理?)

想要在run方法里,既有同步代碼塊又能調用同步函數,這需要什么動作?這叫做線程的切換。為真的時候,運行同步代碼塊:為假的時候,運行同步函數,這需要一個boolean型變量。

(這里的while語句始終感覺沒什么用,為什么要一直保留著?)

?為真的時候,走同步代碼塊,為假的時候,走同步代碼塊。

兩個線程都進到run方法里面去了,它們都有自己的run方法,判斷的變量也是同一變量flag。

DOS結果線程,1線程和0線程都有,但是都在function里面執行。按理說,0線程為真應該在同步代碼塊中執行,怎么跑到同步函數中執行了?理由:主線程開啟以后,創建對象,創建兩個線程。開啟線程1以后,它還持有cpu的執行權,所以瞬間,將t1.start(),t.flag=false,t2.start()這三句話全部都搞定了。一搞定后,這個flag就變為假了,主線程搞完假后,這兩個線程在啟動的時候都是flag=false,因此兩個線程在執行的時候,執行的都是同步函數。(為什么主線程能執行這么多語句?怎么判別主線程和0,1線程是執行的哪些語句?)

有人說這里沒切換啊。可以做切換。

主線程開啟了0線程以后,把它置為假之前,可以讓主線程停一下。也就是調用sleep方法,讓主線程睡一下,這樣0線程就掌握執行權了。

睡了10毫秒。

DOS結果顯示如上。如果兩個線程同步了,就不會出現負的情況,如果沒同步就有可能出現安全問題。

怎么輸出兩個49?操作線程的代碼有四句,obj兩句,function兩句。你判斷完了,我也判斷完了,你沒輸出,我也沒輸出。我49輸出,我也49輸出。

但是,我現在想說的是0號票,打印0號票肯定是不對的。加上同步的居然不安全。為什么?

首先這里面應該有多線程,同步代碼塊里面是一個線程,同步函數里用的又是另一個線程,它們用的 不是一個鎖。如果用的是用一個鎖,代表著同一個鎖里有多個線程,意味著每次只能有一個線程進來。這里可以說明的一點的是,同步函數用的鎖肯定不是obj,那用的是什么鎖?同步函數僅僅是函數上帶了同步性,同步本身不帶鎖。同步代碼塊后面是單獨指定鎖,synchronized是關鍵字,本身并不帶鎖。

應該是函數帶的鎖,函數有對象,函數被調用的時候,必須是對象來調用。函數是被哪個對象調用呢?

函數是被this調用,函數都有自己所屬的this。函數被哪個對象調用?我哪兒知道,我肯定函數是被對象調用,憑什么去操作對應的數據啊?因為持有this。

這個show被誰調用?被run方法調用,至于run方法被誰調用,換句話說run方法所屬于哪個對象。當然屬于t。run方法不是封裝線程任務么?不是把線程任務所屬對象t創建出來了么,那么就是t在調用run方法對象。show怎么獲取的t,當然this嘛。

一般方法調用一般方法,直接寫個this,即this,show();

run方法也屬于this,直接把this寫入同步代碼塊中,哪個對象調用這個run方法,它就代表哪個對象。這個this所指的地址和下面的t地址是一致的

DOS結果顯示,兩者是同一個對象。

現在將添加的兩個輸出語句注釋掉,

繼續編譯運行

0線程和1線程將票賣完了,也不存在0號票。由此可以驗證同步函數使用的鎖是this。

上面的程序可以不用寫那么多,現在為什么寫呢?是為了講解同步函數使用的鎖是this。

同步函數可以是同步代碼塊的簡寫,一簡寫就有前提,有弊端。如果同步代碼塊里的鎖不是this,那就不能用同步函數了。

同步函數雖然簡化,但是鎖是唯一的。

?

?

?

?

?

?

?

?

?

?

?

?

?

轉載于:https://www.cnblogs.com/wsw-bk/p/8033847.html

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

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

相關文章

追求卓越追求完美規范學習_追求新的黃金比例

追求卓越追求完美規范學習The golden ratio is originally a mathematical term. But art, architecture, and design are inconceivable without this math. Everyone aspires to golden proportions as beautiful and unattainable perfection. By visualizing data, we chal…

leetcode 275. H 指數 II

給定一位研究者論文被引用次數的數組(被引用次數是非負整數),數組已經按照 升序排列 。編寫一個方法,計算出研究者的 h 指數。 h 指數的定義: “h 代表“高引用次數”(high citations),一名科研…

Node js開發中的那些旮旮角角 第一部

#前戲 上一周是我到現公司來最忙碌的(最有意思的)一周了,為什么這么說呢?因為項目中需要提供服務端對用戶病人信息的一個匯總并以email的形式分享信息的接口,在幾天的時間里調研處理一套實施方案。我們服務端是Node.js…

文件2. 文件重命名

servlet對本機已存在的文件進行重命名。 .jsp界面 1 <form action"<%basePath %>fileAction" method"get" >2 <table>3 <tr>4 <td>輸入文件路徑</td>5 <td&…

js字符串slice_JavaScript子字符串示例-JS中的Slice,Substr和Substring方法

js字符串sliceIn daily programming, we often need to work with strings. Fortunately, there are many built-in methods in JavaScript that help us while working with arrays, strings and other data types. We can use these methods for various operations like sea…

leetcode 218. 天際線問題

城市的天際線是從遠處觀看該城市中所有建筑物形成的輪廓的外部輪廓。給你所有建筑物的位置和高度&#xff0c;請返回由這些建筑物形成的 天際線 。 每個建筑物的幾何信息由數組 buildings 表示&#xff0c;其中三元組 buildings[i] [lefti, righti, heighti] 表示&#xff1a…

[Android Pro] 終極組件化框架項目方案詳解

cp from : https://blog.csdn.net/pochenpiji159/article/details/78660844 前言 本文所講的組件化案例是基于自己開源的組件化框架項目github上地址github.com/HelloChenJi…其中即時通訊(Chat)模塊是單獨的項目github上地址github.com/HelloChenJi… 1.什么是組件化&#xff…

如何寫一個vue指令directive

舉個例子 &#xff1a;clickoutside.js const clickoutsideContext clickoutsideContext;export default {/*param el 指令所綁定的元素param binding {Object} param vnode vue編譯生成的虛擬節點*/bind (el, binding, vnode) {const documentHandler function(e) {console.…

安裝angular cli_Angular 9適用于初學者—如何使用Angular CLI安裝第一個應用程序

安裝angular cliAngular is one of the most popular JavaScript frameworks created and developed by Google. In the last couple of years, ReactJS has gained a lot of interest and has become the most popular modern JS library in the industry. But this doesn’t …

leetcode 1818. 絕對差值和

給你兩個正整數數組 nums1 和 nums2 &#xff0c;數組的長度都是 n 。 數組 nums1 和 nums2 的 絕對差值和 定義為所有 |nums1[i] - nums2[i]|&#xff08;0 < i < n&#xff09;的 總和&#xff08;下標從 0 開始&#xff09;。 你可以選用 nums1 中的 任意一個 元素來…

【轉載】keil5中加入STM32F10X_HD,USE_STDPERIPH_DRIVER的原因

初學STM32&#xff0c;在RealView MDK 環境中使用STM32固件庫建立工程時&#xff0c;初學者可能會遇到編譯不通過的問題。出現如下警告或錯誤提示&#xff1a; warning: #223-D: function "assert_param" declared implicitly;assert_param(IS_GPIO_ALL_PERIPH(GPIOx…

下崗職工_下崗后我如何獲得多位軟件工程師的面試

下崗職工“Opportunities to find our deeper powers come when life seems most challenging.” -Joseph Campbell“當生活似乎最具挑戰性時&#xff0c;就有機會找到我們更深層的力量。” 約瑟夫坎貝爾 I was recently laid off for the first time in my life. I realized t…

1846. 減小和重新排列數組后的最大元素

給你一個正整數數組 arr 。請你對 arr 執行一些操作&#xff08;也可以不進行任何操作&#xff09;&#xff0c;使得數組滿足以下條件&#xff1a; arr 中 第一個 元素必須為 1 。任意相鄰兩個元素的差的絕對值 小于等于 1 &#xff0c;也就是說&#xff0c;對于任意的 1 <…

bashdb常用命令

一、列出代碼和查詢代碼類&#xff1a; l 列出當前行以下的10行- 列出正在執行的代碼行的前面10行. 回到正在執行的代碼行w 列出正在執行的代碼行前后的代碼/pat/ 向后搜索pat&#xff1f;pat&#xff1f;向前搜索pat二、Debug控制類&#xff1a; h 幫助help 命令 得到…

podcast播客資源_為什么播客是我的新維基百科-完美的非正式學習資源

podcast播客資源In this article, I’ll explain why podcasts replaced a lot of my Wikipedia usage for informal learning. I’ll also talk about how I listen to 5 hours of podcasts every day.在本文中&#xff0c;我將解釋為什么播客代替了我的許多Wikipedia用于非正…

劍指 Offer 53 - I. 在排序數組中查找數字 I(二分法)

統計一個數字在排序數組中出現的次數。 示例 1: 輸入: nums [5,7,7,8,8,10], target 8 輸出: 2 示例 2: 輸入: nums [5,7,7,8,8,10], target 6 輸出: 0 限制&#xff1a; 0 < 數組長度 < 50000 解題思路 先用二分法查找出其中一個目標元素再向目標元素兩邊查找…

MVC與三層架構區別

我們平時總是將三層架構與MVC混為一談&#xff0c;殊不知它倆并不是一個概念。下面我來為大家揭曉我所知道的一些真相。 首先&#xff0c;它倆根本不是一個概念。 三層架構是一個分層式的軟件體系架構設計&#xff0c;它可適用于任何一個項目。 MVC是一個設計模式&#xff0c;它…

tensorflow 實現邏輯回歸——原以為TensorFlow不擅長做線性回歸或者邏輯回歸,原來是這么簡單哇!...

實現的是預測 低 出生 體重 的 概率。尼克麥克盧爾&#xff08;Nick McClure&#xff09;. TensorFlow機器學習實戰指南 (智能系統與技術叢書) (Kindle 位置 1060-1061). Kindle 版本. # Logistic Regression #---------------------------------- # # This function shows ho…

sdlc 瀑布式 生命周期_SDLC指南–軟件開發生命周期的階段和方法

sdlc 瀑布式 生命周期When I decided to teach myself how to code almost four years ago I had never heard of, let alone thought about, the software development life cycle.當我差不多四年前決定教自己如何編碼時&#xff0c;我從未聽說過軟件開發生命周期&#xff0c;…

劍指 Offer 48. 最長不含重復字符的子字符串

請從字符串中找出一個最長的不包含重復字符的子字符串&#xff0c;計算該最長子字符串的長度。 示例 1: 輸入: “abcabcbb” 輸出: 3 解釋: 因為無重復字符的最長子串是 “abc”&#xff0c;所以其長度為 3。 示例 2: 輸入: “bbbbb” 輸出: 1 解釋: 因為無重復字符的最長子…