摘要:一個(gè)線程做完,并將數(shù)據(jù)刷新回主內(nèi)存了,下一個(gè)線程才會(huì)啟動(dòng)。聲明了的變量在被賦值之后,線程會(huì)立刻將值寫(xiě)回主內(nèi)存在讀取變量時(shí),線程會(huì)到主內(nèi)存去讀取變量的最新值。
一個(gè)例子:
public class Counter { public static int count = 0; public synchronized static void inc() { count++; } public static void main(String[] args) { for (int i = 0; i < 100; i++) { new Thread(new Runnable() { @Override public void run() { Counter.inc(); } }).start(); } while(Thread.activeCount() > 1){ Thread.yield(); } System.out.println("運(yùn)行結(jié)果:Counter.count=" + Counter.count); } }
使用線程:
1.新建自定義類(lèi),繼承接口Runnable,并實(shí)現(xiàn)方法run()。
2.實(shí)例化,作為參數(shù)傳給thread(),調(diào)用thread的start方法,運(yùn)行線程。該線程就會(huì)運(yùn)行run()的代碼。
本來(lái),main方法執(zhí)行過(guò)程便是一個(gè)線程,就好比一個(gè)人A在干活。新建一個(gè)線程,就好比又召集了一個(gè)人來(lái)同時(shí)干活。上面的例子中,這新來(lái)的人——新建的線程——將會(huì)和A一起同時(shí)地干活。
所以,如果不在main線程里判斷其他100個(gè)線程是否允許完畢的話,A(main函數(shù)所在線程)可能將會(huì)比其他人有些人干的更快,那么——main函數(shù)的線程先于其他線程跑完,導(dǎo)致打印的結(jié)果不是最終100個(gè)線程跑完的結(jié)果。
synchronized關(guān)鍵字聲明了該方法為同步方法。意即,同時(shí)只允許一個(gè)線程運(yùn)行這個(gè)方法。前面我們說(shuō)過(guò),新建并啟動(dòng)了100個(gè)線程,這100個(gè)人都準(zhǔn)備開(kāi)始干活,但是帶有synchronized關(guān)鍵字的方法只允許同時(shí)一個(gè)人使用。也就是說(shuō)這100個(gè)人需要排隊(duì)等待,先來(lái)后到。
為什么要同步,先來(lái)后到呢?
這里就存在內(nèi)存使用的問(wèn)題。
每一個(gè)線程在使用實(shí)例變量的時(shí)候,會(huì)復(fù)制一份副本到自己的棧內(nèi)存中(每個(gè)線程獨(dú)自享有)。倘若實(shí)例變量為5,現(xiàn)有兩個(gè)線程同時(shí)復(fù)制了5到自己的線程內(nèi)存。他們各自做加1操作,隨后線程A將結(jié)果6,寫(xiě)回到主內(nèi)存中;隨后線程B也將6寫(xiě)回到主內(nèi)存中。
但是我們的初衷可能是需要該變量作為計(jì)數(shù)器,反映所做操作的次數(shù),但是這里兩個(gè)線程共做了2次操作,變量的值卻只加了1。
這個(gè)時(shí)候,使用synchronized,方法就會(huì)“同步”。一個(gè)線程做完,并將數(shù)據(jù)刷新回主內(nèi)存了,下一個(gè)線程才會(huì)啟動(dòng)。
就好比,房子里有一個(gè)房間,想進(jìn)入的人必須拿到門(mén)口的桌子上放著的一把鑰匙,沒(méi)有鑰匙的人只可在門(mén)外等候。只有等這個(gè)人做完所有工作,并且把鑰匙還回門(mén)口的桌子,下一個(gè)人才能從桌子拿到鑰匙,進(jìn)入房間。
volatile
Java還提供了關(guān)鍵字volatile。聲明了volatile的變量在被賦值之后,線程會(huì)立刻將值寫(xiě)回主內(nèi)存;在讀取變量時(shí),線程會(huì)到主內(nèi)存去讀取變量的最新值。說(shuō)白了,它增加了線程與主內(nèi)存的通信,以期望解決多線程寫(xiě)數(shù)據(jù)的同步問(wèn)題。
但這也并不一定能保證上述計(jì)數(shù)器的問(wèn)題。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/66407.html
摘要:哪吒社區(qū)技能樹(shù)打卡打卡貼函數(shù)式接口簡(jiǎn)介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號(hào)作者架構(gòu)師奮斗者掃描主頁(yè)左側(cè)二維碼,加入群聊,一起學(xué)習(xí)一起進(jìn)步歡迎點(diǎn)贊收藏留言前情提要無(wú)意間聽(tīng)到領(lǐng)導(dǎo)們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨(dú)立帶隊(duì)的人太少,簡(jiǎn)而言之,不缺干 ? 哪吒社區(qū)Java技能樹(shù)打卡?【打卡貼 day2...
摘要:最近聽(tīng)很多面試的小伙伴說(shuō),網(wǎng)上往往是一篇一篇的多線程的文章,除了書(shū)籍沒(méi)有什么學(xué)習(xí)多線程的一系列文章。將此線程標(biāo)記為線程或用戶線程。 最近聽(tīng)很多面試的小伙伴說(shuō),網(wǎng)上往往是一篇一篇的Java多線程的文章,除了書(shū)籍沒(méi)有什么學(xué)習(xí)多線程的一系列文章。但是僅僅憑借一兩篇文章很難對(duì)多線程有系統(tǒng)的學(xué)習(xí),而且面試的時(shí)候多線程這方面的知識(shí)往往也是考察的重點(diǎn),所以考慮之下決定寫(xiě)一系列關(guān)于Java多線程的文章...
摘要:我的學(xué)習(xí)筆記匯總標(biāo)簽筆記分為兩大部分和筆記內(nèi)容主要是對(duì)一些基礎(chǔ)特性和編程細(xì)節(jié)進(jìn)行總結(jié)整理,適合了解基礎(chǔ)語(yǔ)法,想進(jìn)一步深入學(xué)習(xí)的人如果覺(jué)得不錯(cuò),請(qǐng)給,這也是對(duì)我的鼓勵(lì),有什么意見(jiàn)歡迎留言反饋目錄基礎(chǔ)鞏固筆記反射基礎(chǔ)鞏固筆記泛型基礎(chǔ)鞏 我的java&javaweb學(xué)習(xí)筆記(匯總) 標(biāo)簽: java [TOC] 筆記分為兩大部分:javase和javaweb javase javawe...
摘要:包含了支持服務(wù)開(kāi)發(fā)的類(lèi),并為提供基礎(chǔ),如語(yǔ)言基礎(chǔ)操作操作網(wǎng)絡(luò)通信以及多線程等技術(shù)。在運(yùn)行文件時(shí),的解釋器對(duì)這些字節(jié)碼進(jìn)行解釋執(zhí)行,執(zhí)行過(guò)程中需要加入的類(lèi)在連接階段被載入到運(yùn)行環(huán)境中。支持多個(gè)線程同時(shí)執(zhí)行,并提供多線程之間的同步機(jī)制。 1.什么是Java語(yǔ)言 簡(jiǎn)單地說(shuō),Java 是由 Sun Microsystems 公司于 1995 年推出的一門(mén)面向?qū)ο蟪绦蛟O(shè)計(jì)語(yǔ)言。2009 年 Or...
閱讀 1872·2021-09-28 09:35
閱讀 1207·2019-08-30 15:54
閱讀 1732·2019-08-30 15:44
閱讀 3428·2019-08-30 14:09
閱讀 576·2019-08-29 14:05
閱讀 2754·2019-08-28 17:53
閱讀 2101·2019-08-26 13:41
閱讀 1787·2019-08-26 13:26