国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

香港云服务器
服務器之家 - 編程語言 - JAVA教程 - Java多線程編程中易混淆的3個關鍵字總結

Java多線程編程中易混淆的3個關鍵字總結

2019-12-13 10:42junjie JAVA教程

這篇文章主要介紹了Java多線程編程中易混淆的3個關鍵字總結,本文總結了、volatile、ThreadLocal、synchronized等3個關鍵字,對這幾個容易混淆概念的關鍵字分別做了講解,需要的朋友可以參考下

概述

最近在看《ThinKing In Java》,看到多線程章節時覺得有一些概念比較容易混淆有必要總結一下,雖然都不是新的東西,不過還是蠻重要,很基本的,在開發或閱讀源碼中經常會遇到,在這里就簡單的做個總結。

1.volatile

volatile主要是用來在多線程中同步變量。

在一般情況下,為了提升性能,每個線程在運行時都會將主內存中的變量保存一份在自己的內存中作為變量副本,但是這樣就很容易出現多個線程中保存的副本變量不一致,或與主內存的中的變量值不一致的情況。

而當一個變量被volatile修飾后,該變量就不能被緩存到線程的內存中,它會告訴編譯器不要進行任何移出讀取和寫入操作的優化,換句話說就是不允許有不同于“主”內存區域的變量拷貝,所以當該變量有變化時,所有調用該變量的線程都會獲得相同的值,這就確保了該變量在應用中的可視性(當一個任務做出了修改在應用中必須是可視的),同時性能也相應的降低了(還是比synchronized高)。

但需要注意volatile只能確保操作的是同一塊內存,并不能保證操作的原子性。所以volatile一般用于聲明簡單類型變量,使得這些變量具有原子性,即一些簡單的賦值與返回操作將被確保不中斷。但是當該變量的值由自身的上一個決定時,volatile的作用就將失效,這是由volatile關鍵字的性質所決定的。

所以在volatile時一定要謹慎,千萬不要以為用volatile修飾后該變量的所有操作都是原子操作,不再需要synchronized關鍵字了。

2.ThreadLocal

首先ThreadLocal和本地線程沒有一毛錢關系,更不是一個特殊的Thread,它只是一個線程的局部變量(其實就是一個Map),ThreadLocal會為每個使用該變量的線程提供獨立的變量副本,所以每一個線程都可以獨立地改變自己的副本,而不會影響其它線程所對應的副本。這樣做其實就是以空間換時間的方式(與synchronized相反),以耗費內存為代價,單大大減少了線程同步(如synchronized)所帶來性能消耗以及減少了線程并發控制的復雜度。

個人覺得比較典型的例子就是在Android關于Looper的源碼中對ThreadLocal的使用,同時也包含了ThreadLocal的基本用法,具體代碼如下:

  1. public class Looper {  
  2. private static final String TAG = "Looper"
  3.   
  4. // sThreadLocal.get() will return null unless you've called prepare().  
  5. private static final ThreadLocal sThreadLocal = new ThreadLocal();  
  6.   
  7. ......  
  8.   
  9. private static Looper mMainLooper = null;  
  10.   
  11. ......  
  12.   
  13. public static final void prepare() {  
  14.   if (sThreadLocal.get() != null) {  
  15.     throw new RuntimeException("Only one Looper may be created per thread");  
  16.   }  
  17.   sThreadLocal.set(new Looper());  
  18. }  
  19.   
  20. ......  
  21.   
  22. public static final void prepareMainLooper() {  
  23.   prepare();  
  24.   setMainLooper(myLooper());  
  25.   
  26.   ......  
  27.   
  28. }  
  29.   
  30. private synchronized static void setMainLooper(Looper looper) {  
  31.   mMainLooper = looper;  
  32. }  
  33. public synchronized static final Looper getMainLooper() {  
  34.   return mMainLooper;  
  35. }  
  36.   
  37. ......  
  38.   
  39. public static final Looper myLooper() {  
  40.   return (Looper)sThreadLocal.get();  
  41. }  
  42.   
  43. ......  
  44.   

但需要注意的是,雖然ThreadLocal和Synchonized都用于解決多線程并發訪問,ThreadLocal與synchronized還是有本質的區別。synchronized是利用鎖的機制,使變量或代碼塊在某一時該只能被一個線程訪問。而ThreadLocal為每一個線程都提供了變量的副本,使得每個線程在某一時間訪問到的并不是同一個對象,這樣就隔離了多個線程對數據的數據共享。而Synchronized卻正好相反,它用于在多個線程間通信時能夠獲得數據共享。即Synchronized用于線程間的數據共享,而ThreadLocal則用于線程間的數據隔離。所以ThreadLocal并不能代替synchronized,Synchronized的功能范圍更廣(同步機制)。

3.synchronized

synchronized關鍵字是Java利用鎖的機制自動實現的,一般有同步方法和同步代碼塊兩種使用方式。Java中所有的對象都自動含有單一的鎖(也稱為監視器),當在對象上調用其任意的synchronized方法時,此對象被加鎖(一個任務可以多次獲得對象的鎖,計數會遞增),同時在線程從該方法返回之前,該對象內其他所有要調用類中被標記為synchronized的方法的線程都會被阻塞。當然針對每個類也有一個鎖(作為類的Class對象的一部分),所以你懂的^.^。

最后需要注意的是synchronized是同步機制中最安全的一種方式,其他的任何方式都是有風險的,當然付出的代價也是最大的。

延伸 · 閱讀

精彩推薦
316
主站蜘蛛池模板: www.久久.com | 香蕉久久一区二区不卡无毒影院 | 黄色一级片在线观看 | 欧美国产精品一区二区三区 | 久久久久久久 | 国产精品国产成人国产三级 | 国产在线中文字幕 | 久久中文在线观看 | 欧美国产精品一区二区三区 | 91av在| 免费激情 | 91精品国产高清久久久久久久久 | 亚洲国产精品久久 | 玖玖精品视频 | 国产亚洲精品精品国产亚洲综合 | 国产精品久久久久久久久 | 岛国免费 | 99久久精品国产一区二区三区 | 久久国产精品免费一区二区三区 | 午夜在线电影 | jdav视频在线观看免费 | 好看毛片| 黄色免费观看网站 | 久久精彩免费视频 | 国产欧美精品区一区二区三区 | 在线欧美亚洲 | 久久综合成人精品亚洲另类欧美 | 欧美一级片 | 人人爱人人爽 | 久久激情久久 | 91精品在线看 | 欧美精品在线一区二区三区 | 久久久久久亚洲一区二区三区蜜臀 | 日本在线观看一区 | 麻豆国产一区二区三区 | 久久久久久久久一区二区三区 | 亚洲精品网址 | 精品久 | 亚洲国产一区视频 | 一区二区视频在线 | 精品视频网站 |