亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

java 線程及synchronized關鍵字

2019-11-06 06:01:50
字體:
來源:轉載
供稿:網友

     從本篇開始,我們將會逐漸總結關于java并發這一塊的內容,也可以理解為是我的筆記,主要來自于一些博客和java書籍中的內容,所有的內容都是來自于他們之中并且加上了我自己的理解和認識。      我們將會從以下的幾點理解java線程的一些概念:

線程的基本概念和優劣之處創建一個線程的兩種方式線程的屬性線程的狀態synchronized可修飾的方法synchronized的重要特性 一、線程的基本概念      在計算機中有進程和線程這么兩個概念,進程中可以有多個線程,它們是從屬關系,進程往往更像是資源的占有者,線程才是程序的執行者,多個線程之間共享著進程中的資源。一個cpu同時只能運行一個線程,每個線程都有一個時間片,時間片用完了就會被阻塞并讓出CPU的控制權,交給下一個線程使用。這樣在計算機中就可以實現多任務的假象,其實CPU在不斷的切換線程,好像多個任務在同時運行。      使用線程的優勢毋庸置疑,可以增加CPU的執行效率,一旦某個線程需要等待某種資源(例如:等待打印機),就可以將它阻塞釋放CPU讓CPU執行別的線程,而不需要讓CPU和此線程一起等待某種資源從而提高系統效率,另外一點就是可以用這種假象增加用戶體驗度。但是,CPU在切換不同線程之間所要花費的代價也是不可忽視的,在較為復雜的程序中這種劣勢可能九流一毛,但是如果在簡單的程序中就會顯得尤為突出。      二、創建一個線程           接下來我們看看如何在java中創建一個線程來實現多個線程同時運行。第一種方式,java 中有一個類Thread,我們只要繼承這個類并重寫他的run方法,調用start方法就可以啟動一個新的線程了。(沒見過的同學可能不能理解以下代碼,下面我會解釋)/*聲明自己的一個線程類*/public class Test_thread extends Thread { //重寫Thread類中的run方法 public void run(){ System.out.           首先我們先了解一下,一個線程被創建之后,怎么才能啟動運行,我們調用thread.start();方法啟動一個線程,首先就會執行我們重寫的run方法(如果沒有重寫就會調用Thread類的run方法,什么也不做,這也是我們重寫run方法的原因),也就是說run方法是一個線程的開始。有個疑問,為什么調用start方法,卻執行了run方法了?其實調用start方法就是為線程的啟動做準備操作,分配線程私有的堆棧資源,然后執行run方法。           下面我們看創建一個線程的第二種方式,實現接口Runnable,并重寫其中的run方法。

public class Test_thread implements Runnable { public void run(){ System.out.println("i am the thread"); }}public class Test_Class { public static void main(String[] args){ Test_thread thread = new Test_thread(); thread.start();//編譯錯誤 }}

          我們會發現雖然重寫了run方法,但是在調用start方法的時候卻編譯錯誤,我們進入到Runnable接口的源代碼中可以看到,只有一個抽象方法run,所以沒有啟動線程的start方法,所以我們還是要借助Tread類。

public class Test_Class { public static void main(String[] args){ Thread thread = new Thread(new Test_thread()); thread.start(); }}

          因為Thread類中有start方法,所以可以使用Thread的一個構造函數傳入一個實現了Runnable接口的類型,構建一個Thread類。      三、線程的屬性和狀態           在一個多線程的程序中我們使用線程的一些屬性來區別和辨認它們:

private long tid;private volatile char name[];public static native Thread currentThread()private boolean daemon = false;private volatile int threadStatus = 0;public final static int NORM_PRIORITY = 5;

          每個線程會有一個tid指定此線程的在所有線程中的排序,這個值是遞增的,還有一個name指定該線程的名字,也可以使用setName設置一個優雅的線程名字,Thread類還提供了一個方法返回當前正在占用CPU的線程對象。每個線程在某個時刻都是有狀態的,屬性threadStatus記錄了當前對象線程的狀態是什么,默認情況下,所有的線程的優先級都被置為5,如果有特殊需要可以修改線程的優先級,使得某個線程可以優先得到運行。下面介紹線程的幾種不同的狀態。

New:線程剛剛被創建,還沒有被啟動。Runnable:線程處于可運行的狀態,但是不一定處于正在運行的狀態(后面解釋區別)Blocked:線程處于被阻塞的狀態,一般是請求某資源不成功于是讓出CPU阻塞自己(具體的區別后面說)Waiting:線程處于等待狀態,一般是等待服務Terminated:線程終止,也就是線程被kill,釋放其占用的資源

          下面具體的說說不同狀態下的線程的一些操作,首先看看new,線程從此被創建,只是離運行狀態還需要一些準備。Runnable表示線程是可運行,至于是否已經處于運行狀態還要看系統給的時間片是否用完,如果用完了就會將此線程放置在可運行線程隊列的尾部,等待下次分配時間片,如果時間片沒有用完,就是處于運行狀態的(這也是為什么叫做Runnable而不是Running的原因)。接下來的兩種狀態Blocked和waiting都表示線程阻塞,需要讓出CPU。只是導致它們處于這種狀態的原因不一樣,具體的在我們介紹完synchronized關鍵字之后就會不言而喻了。      四、關鍵字synchronized           先看一段代碼:

public class Test_thread extends Thread{ public static int count = 0; public void run(){ try { Thread.sleep((int) (Math.random() * 100)); }catch(InterruptedException e){ } count++; }}public class Test_Class { public static void main(String[] args){ Test_thread[] thread = new Test_thread[1000]; for(int a=0;a<1000;a++){ thread[a] = new Test_thread(); thread[a].start(); } for(int a=0;a<1000;a++){ try { thread[a].join(); }catch (InterruptedException e){ } } System.out.println(Test_thread.count); }}

     按照直覺,創建1000個線程,每個線程隨機睡覺并將公共變量增一,main線程等待所有線程執行結束之后,輸出公共變量的值。按照直覺答案應該是1000,但是我們運行的結果每次都是不一樣的,接近1000但每次都不一樣。這是為什么呢?這其實就是簡單的模擬了高并發,可能有幾個線程睡了相同的時間,同時醒來獲取的count值是相同的,這就導致這幾個線程對count的操作被覆蓋了。

public class Test_thread extends Thread{ public static int count = 0; public void run(){ try { Thread.sleep((int) (Math.random() * 100)); }catch(InterruptedException e){ } /*使用關鍵字*/ synchronized (Test_thread.class){ count++; } }}

          一個簡單的關鍵字就可以輕松解決這樣的高并發的問題。至于為什么這么寫?在介紹完synchronized關鍵字之后,想必你就會知道了。           首先我們需要知道,每個對象都有一把內部鎖。所以被synchronized關鍵字修飾的方法,其實是被加了內部對象鎖。我們看代碼:

public class Counter{ private int count; /*為實例方法加此關鍵字*/ public synchronized int getCount(){ return count; } }

          為實例方法添加關鍵字,實際上就是給當前的對象加鎖;括號中就是要加鎖的對象。

public class Counter{ private int count; /*為實例方法加此關鍵字*/ synchronized(this){ return count; } }

          對于靜態方法,實際上就是為這個類加上鎖;

public class Counter{ private static int count; public static synchronized int getCount(){ return count; } }/*實際上給這個類加上鎖*/ public class Counter{ private int count; synchronized(Counter.class){ return count; } }

     五、深入理解synchronized的一些特性           第一個性質是:可重入性。被synchronized修飾的方法中的所有操作都是原子操作,但是當我們需要在其中訪問另外的一些需要鎖的代碼時候,可以直接獲取別的鎖。也就是當前的對象是可以獲得多個鎖的。           第二個性質是:內存的可見性。在我們的計算機中,其實有很多的操作并不是很”干脆”的,比如你向數據庫中存數據時,其實很多時候一些待存入的數據積累在緩存中等到一定數據量的時候才會統一的存入數據庫,但是在我們看來這些數據其實應該早就存入數據庫了。這就導致了一個內存的不可見性問題。當然我們也是可以使用關鍵字synchronized來保證每次取出的數據都是最新的。在釋放鎖的時候會立即將數據協會內存,獲得鎖的時候會去讀取最新的內容。

public class Counter{ private int count; public synchronized int getCount(){ return count; } } /*每次獲得該對象的鎖之后,去獲取最新的count數值*/

          其實,如果僅僅是要保證內存的不可見性,使用synchronized關鍵字可能代價有點高,在這種情況下,我們可以使用關鍵字volatile。

public class Counter{ /*使用關鍵字volatile*/ private volatile int count; public int getCount(){ return count; } } /*此關鍵字保證每次使用count的時候數據都是最新的*/

          本篇文章到此結束,還是希望大家發現其中錯誤直接指出,方便我糾正錯誤,更新知識。java并發系列文章,希望大家多多關注。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美风情在线观看| 亚洲肉体裸体xxxx137| 日韩精品免费在线视频观看| 最近的2019中文字幕免费一页| 色狠狠久久aa北条麻妃| 日韩国产精品视频| 亚洲国产精品人人爽夜夜爽| 日韩中文字幕在线精品| 久久久天堂国产精品女人| 国产精品入口日韩视频大尺度| 欧美日韩国产成人在线| 国产精品久久久久久久天堂| 亚洲3p在线观看| 成年无码av片在线| 91精品在线播放| 精品日韩美女的视频高清| 欧美精品成人91久久久久久久| 国产伦精品一区二区三区精品视频| 26uuu久久噜噜噜噜| 成人黄色在线播放| 欧美性色xo影院| 欧美激情精品久久久久久| 久久91亚洲精品中文字幕奶水| 久久69精品久久久久久久电影好| 欧美激情免费观看| 久久69精品久久久久久久电影好| 国产成人精品久久| 欧美极品欧美精品欧美视频| 亚洲iv一区二区三区| 日韩精品丝袜在线| 亚洲福利在线视频| 91影视免费在线观看| 欧美一区二区三区免费视| 92版电视剧仙鹤神针在线观看| 国产精品国产三级国产专播精品人| 久久精品99无色码中文字幕| 91免费视频国产| 久久久久久久一| 97免费视频在线| 亚洲激情小视频| 久久精品国产69国产精品亚洲| 日韩中文字幕欧美| 最近中文字幕日韩精品| 亚洲少妇中文在线| 日本一区二区不卡| 亚洲成人aaa| 色综久久综合桃花网| 国产亚洲精品一区二555| 亚洲国产中文字幕久久网| 亚洲国产日韩欧美在线动漫| 一区二区三区国产视频| 亚洲欧美日韩一区在线| 91九色国产在线| 欧美精品日韩www.p站| 国产精品午夜国产小视频| 欧美影院在线播放| 成人伊人精品色xxxx视频| 国产丝袜一区二区三区| 欧美亚洲国产日本| 91国产精品91| 国产欧美一区二区三区在线看| 国产精品va在线播放我和闺蜜| 国产精品情侣自拍| 久久全国免费视频| 综合激情国产一区| 黑人巨大精品欧美一区二区三区| 国产精品美女www| 欧美性猛交xxxx富婆弯腰| 亚洲精美色品网站| 欧美精品aaa| 国产精品99久久久久久久久久久久| 欧美性猛交丰臀xxxxx网站| 992tv成人免费视频| 国模精品一区二区三区色天香| 欧美日韩国产在线| 欧美日本黄视频| 国产成人免费av| 一区二区三区回区在观看免费视频| 亚洲香蕉成视频在线观看| 欧美精品在线极品| 久久这里只有精品视频首页| 国产视频在线观看一区二区| 日韩精品高清在线观看| 国产区精品在线观看| 国产成人亚洲精品| 日韩视频免费大全中文字幕| 最近中文字幕mv在线一区二区三区四区| 日韩有码在线观看| 亚洲一区二区日本| 成人av.网址在线网站| 国产欧美精品一区二区三区介绍| 国产精品va在线播放| 国产69久久精品成人| 亚洲人成绝费网站色www| 综合网中文字幕| 精品视频中文字幕| 欧美视频在线观看免费网址| 2019中文字幕免费视频| 国产精品成人品| 欧美精品免费在线观看| 欧美日韩一区二区在线| 按摩亚洲人久久| 亚洲网站在线看| 久久精品国产欧美激情| 国产91久久婷婷一区二区| 亚洲一级免费视频| 久久精品国产69国产精品亚洲| 精品一区二区亚洲| 精品久久久在线观看| 欧美久久久精品| 色偷偷偷综合中文字幕;dd| 国产精品久久久久久久久借妻| 色偷偷9999www| 国产精品成人播放| 精品国产一区二区三区久久久狼| 久久久久久久久久av| 欧美性极品少妇精品网站| 亚洲影视中文字幕| 一区二区欧美日韩视频| 538国产精品一区二区免费视频| 久久久999精品免费| 欧美国产视频日韩| 色狠狠久久aa北条麻妃| 色婷婷久久一区二区| 欧美在线视频免费观看| 亚洲图片欧美日产| 亚洲久久久久久久久久久| 在线观看精品国产视频| 性欧美xxxx视频在线观看| 国产精品视频免费在线观看| 亚洲国产精久久久久久久| 日韩电视剧在线观看免费网站| 欧美人成在线视频| 欧美怡红院视频一区二区三区| 欧美日韩激情美女| 欧美香蕉大胸在线视频观看| 中文字幕日韩av电影| 久久久亚洲天堂| 国产精品成av人在线视午夜片| 国产精品专区h在线观看| 亚洲第一网站免费视频| 久久久精品亚洲| 在线播放国产精品| 97精品视频在线播放| 91精品在线播放| 成人黄色免费在线观看| 欧美精品在线网站| 日韩免费观看网站| 国产综合视频在线观看| 91精品视频播放| 欧美日韩中文字幕在线| 浅井舞香一区二区| 亚洲电影在线观看| 日韩av电影手机在线| 日韩精品中文字幕久久臀| 日韩av一卡二卡| 国产97色在线| 亚洲精品成人久久久| 成人国产精品av| 久久久影视精品| 亚洲欧美在线一区二区| 亚洲欧美日韩国产精品| 久久人人97超碰精品888| 国产精品一区二区三区久久|