整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Fences4使用教程

          Fences4使用教程

          ences4使用教程

          1.我們完成Fences4軟件安裝之后,打開軟件系統便會自動彈出相應的窗口,接著我們選擇第一個安裝文件類型進行自動整理,便會出現如下界面;

          2.然后我們來講講軟件最核心的功能--畫區,該功能有兩種操作方式,一種是我們拖動鼠標右鍵創建合適的軟件程序分區,接著把相應的文件扔進去就好了;

          3.另一種專門針對桌面文件夾所打造的,我們可以直接在右鍵菜單中選擇「在桌面上顯示此文件夾」,然后快速創建分區;

          4.這樣一來,我們就無需花費時間在從資源管理器中查看文件夾內容,我們可以直接點擊Fences分區,一層層進入到文件夾內容中去,省去了不少繁瑣的操作步驟;

          5.全局置頂是針對最新版本所推出的功能,我們可以利用快捷鍵「Win+空格」和「Win+Ctrl+空格」在桌面任意界面調出分區面板;

          6.此外,還為桌面還配有隱藏的功能,你可以雙擊桌面直接隱藏,需要使用時雙擊桌面重新顯示;

          7.也可以在設置里啟用不適用桌面時自動隱藏圖標的功能,眼不見心不煩,切回桌面或雙擊時再顯示圖標;

          8.除了上面介紹的這些,Fences 的強大還體現在——支持桌面自動快照備份,以防桌面出岔子;

          9.桌面上、分區內,所有文件可按打開次數排序;

          10.只要你合理搭配 Fences 的功能,你完全可以實現這樣的效果。

          教程來源于:https://www.81857.net/soft/63210.html


          本文討論什么是內存屏障(其實它是軟件協調硬件工作的一個指令),以及如何應用volatile(在JAVA世界中內存屏障的語義是由volatile關鍵字來實現的),最后介紹在disruptor中如何應用的。

          什么是內存屏障



          它是一個CPU指令。我們在討論CPU級別的東西,以便獲得我們想要的性能(Martin著名的Mechanical Sympathy理論https://mechanical-sympathy.blogspot.com/2011/07/memory-barriersfences.html)。


          基本上,它是這樣一條指令: a)確保一些特定操作執行的順序; b)影響一些數據的可見性(可能是某些指令執行后的結果)。

          編譯器和CPU可以在保證輸出結果一樣的情況下對指令重排序,使性能得到優化。插入一個內存屏障,相當于告訴CPU和編譯器先于這個命令的必須先執行,后于這個命令的必須后執行。

          內存屏障另一個作用是強制更新一次不同CPU的緩存。例如,一個寫屏障會把這個屏障前寫入的數據刷新到緩存,這樣任何試圖讀取該數據的線程將得到最新值,而不用考慮到底是被哪個cpu核心或者哪顆CPU執行的。

          和JAVA什么關系



          JAVA里有個關鍵字叫volatile,在JAVA世界中內存屏障的語義是由volatile關鍵字來實現的。JAVA 語言是支持多線程的,為了解決多線程的安全問題 JAVA 語言引進了 synchronized 同步塊和 volatile關鍵字機制。

          volatile是輕量級的synchronized,它在多處理器開發中保證了共享變量的“可見性”。可見性的意思是當一個線程修改一個共享變量時,另外一個線程能讀到這個修改的值。

          為什么要使用volatile



          解決多線程下數據安全共享的問題;volatile變量修飾符如果使用恰當的話,它比synchronized的使用和執行成本會更低,因為它不會引起線程上下文的切換和調度。


          volatile的實現原理



          那么Volatile是如何來保證可見性的呢?在x86處理器下通過工具獲取JIT編譯器生成的匯編指令來看看對Volatile進行寫操作CPU會做什么事情。

          Java代碼:

          instance=new Singleton();//instance是volatile變量

          匯編代碼:

          0x01a3de1d: movb >0x01a3de1d: movb $0x0,0x1104800(%esi);0x01a3de24: lock addl >addl $0x0,(%esp);<>


          有volatile變量修飾的共享變量進行寫操作的時候會多第二行匯編代碼,通過查IA-32架構軟件開發者手冊可知,lock前綴的指令在多核處理器下會引發了兩件事情。

          • 將當前處理器緩存行的數據會寫回到系統內存。
          • 這個寫回內存的操作會引起在其他CPU里緩存了該內存地址的數據無效。


          處理器為了提高處理速度,不直接和內存進行通訊,而是先將系統內存的數據讀到內部緩存(L1,L2或其他)后再進行操作,但操作完之后不知道何時會寫到內存,如果對聲明了Volatile變量進行寫操作,JVM就會向處理器發送一條Lock前綴的指令,將這個變量所在緩存行的數據寫回到系統內存。但是就算寫回到內存,如果其他處理器緩存的值還是舊的,再執行計算操作就會有問題,所以在多處理器下,為了保證各個處理器的緩存是一致的,就會實現緩存一致性協議,每個處理器通過嗅探在總線上傳播的數據來檢查自己緩存的值是不是過期了,當處理器發現自己緩存行對應的內存地址被修改,就會將當前處理器的緩存行設置成無效狀態,當處理器要對這個數據進行修改操作的時候,會強制重新從系統內存里把數據讀到處理器緩存里。


          小貼士:

          這兩件事情在IA-32軟件開發者架構手冊的第三冊的多處理器管理章節(第八章)中有詳細闡述。

          Lock前綴指令會引起處理器緩存回寫到內存。Lock前綴指令導致在執行指令期間,聲言處理器的 LOCK# 信號。在多處理器環境中,LOCK# 信號確保在聲言該信號期間,處理器可以獨占使用任何共享內存。(因為它會鎖住總線,導致其他CPU不能訪問總線,不能訪問總線就意味著不能訪問系統內存),但是在最近的處理器里,LOCK#信號一般不鎖總線,而是鎖緩存,畢竟鎖總線開銷比較大。在8.1.4章節有詳細說明鎖定操作對處理器緩存的影響,對于Intel486和Pentium處理器,在鎖操作時,總是在總線上聲言LOCK#信號。

          但在P6和最近的處理器中,如果訪問的內存區域已經緩存在處理器內部,則不會聲言LOCK#信號。相反地,它會鎖定這塊內存區域的緩存并回寫到內存,并使用緩存一致性機制來確保修改的原子性,此操作被稱為“緩存鎖定”,緩存一致性機制會阻止同時修改被兩個以上處理器緩存的內存區域數據。

          一個處理器的緩存回寫到內存會導致其他處理器的緩存無效IA-32處理器和Intel 64處理器使用MESI(修改,獨占,共享,無效)控制協議去維護內部緩存和其他處理器緩存的一致性。在多核處理器系統中進行操作的時候,IA-32 和Intel 64處理器能嗅探其他處理器訪問系統內存和它們的內部緩存。它們使用嗅探技術保證它的內部緩存,系統內存和其他處理器的緩存的數據在總線上保持一致。例如在Pentium和P6 family處理器中,如果通過嗅探一個處理器來檢測其他處理器打算寫內存地址,而這個地址當前處理共享狀態,那么正在嗅探的處理器將無效它的緩存行,在下次訪問相同內存地址時,強制執行緩存行填充。


          volatile使用誤區




          volatile很容易被誤用,用來進行原子性操作。

          與使用 synchronized相比,聲明一個 volatile 字段的區別在于沒有涉及到鎖操作。但特別的是對 volatile 字段進行“ ++ ”這樣的讀寫操作不會被當做原子操作執行。同時測試了字符串拼接的操作,也是不安全的。下文中有代碼已經證實 volatile 關鍵字修飾的變量在多線程寫的情況下不安全。


          public class Counter {
          //    public volatile static int count=0;
          
          
              public volatilestatic StringBuilder count=new StringBuilder("aa");
          
          
              public static void inc(String a){
                  //這里延遲1毫秒,使得結果明顯
                  try {
                      Thread.sleep(1);
                  } catch (InterruptedExceptione) {
          
          
                  }
                      count .append(a+"-");
          
          
              }
          
          
              public static void main(String[]args) {
                  //同時啟動1000個線程,去進行i++計算,看看實際結果
                  for (int i=1; i <=1000; i++) {
                      int finalI=i;
                      new Thread(new Runnable(){
                          @Override
                          publicvoid run() {
                             Counter.inc(String.valueOf(finalI));
                          }
                      }).start();
                  }
                  //這里每次運行的值都有可能不同,可能為1000
                  System.out.println("運行結果:Counter.count=" + Counter.count);
              }
          }



          運行結果還是沒有我們期望的 aa-XX-1000,下面我們分析一下原因。


          在 java 垃圾回收整理一文中,描述了 jvm 運行時刻內存的分配。其中有一個內存區域是 jvm 虛擬機棧,每一個線程運行時都有一個線程棧,線程棧保存了線程運行時候變量值信息。當線程訪問某一個對象時候值的時候,首先通過對象的引用找到對應在堆內存的變量的值,然后把堆內存變量的具體值 load 到線程本地內存中,建立一個變量副本,之后線程就不再和對象在堆內存變量值有任何關系,變量的具體值 load 到線程本地內存中,建立一個變量副本,之后線程就不再和對象在堆內存變量值有任何關系,而是直接修改副本變量的值,在修改完之后的某一個時刻(線程退出之前),自動把線程變量副本的值回寫到對象在堆中變量。這樣在堆中的對象的值就產生變化了。下面一幅圖描述這些交互。



          read and load 從主存復制變量到當前工作內存

          use and assign 執行代碼,改變共享變量值

          store and write 用工作內存數據刷新主存相關內容, 其中 use and assign 可以多次出現,但是這一些操作并不是原子性,也就是在 read load 之后,如果主內存 count 變量發生修改之后,線程工作內存中的值由于已經加載,不會產生對應的變化,所以計算出來的結果會和預期不一樣。

          對于 volatile 修飾的變量, jvm 虛擬機只是保證從主內存加載到線程工作內存的值是最新的。

          例如假如線程 1 ,線程 2 在進行 read,load 操作中,發現主內存中 count 的值都是 5 ,那么都會加載這個最新的值

          在線程 1 堆 count 進行修改之后,會 write 到主內存中,主內存中的 count 變量就會變為 6

          線程 2 由于已經進行 read,load 操作,在進行運算之后,也會更新主內存 count的變量值為 6

          導致兩個線程及時用 volatile 關鍵字修改之后,還是會存在并發的情況。


          暫且不管在多線程下對 volatile 修飾的變量進行修改是否安全的,但是在多線程下對 volatile 修飾的變量進行讀操作是安全的,后一點是無可非議的。所以有了以下的結論: volatile 的適用場景當只有一個線程可以修改字段的值,其它線程可以隨時讀取,那么把字段聲明為 volatile 是合理的。


          對性能的影響



          內存屏障作為另一個CPU級的指令,沒有鎖那樣大的開銷,可以看之前文章

          Disruptor為什么會如此快 - (一)鎖的成本的實驗結果。內核并沒有在多個線程間干涉和調度。

          Disruptor如何使用內存屏障



          下圖是Disruptor的AbsttactSequencer源碼截圖。



          把Sequence定義為volatile 類型,供多線程共享。從截圖可以看出gatingSequences在對象實例化時進行了初始化(寫操作),多處進行讀操作。這個與先前得出的結論頗為相似:volatile 的適用場景當只有一個線程可以修改字段的值,其它線程可以隨時讀取,那么把字段聲明為 volatile 是合理的。


          小結



          1、內存屏障是CPU指令,它允許你對數據什么時候對其他進程可見作出假設。在Java世界里,使用volatile關鍵字來實現內存屏障。使用volatile意味著不用被迫選擇加鎖,并且還能獲得性能的提升。

          2、volatile的適用場景:當只有一個線程可以修改字段的值,其它線程可以隨時讀取,那么把字段聲明為 volatile 是合理的。


          如果此文能幫小伙伴答疑解惑,請關注「架構那些事兒」

          你的關注就是我的動力!

          多人都喜歡用外國軟件,其實有很多國產軟件也非常好用,今天給大家推薦6個優質的國產軟件,款款精挑細選,讓你的Windows電腦更好用。

          01.Fences(桌面瞬間整潔)

          這是一款專注于桌面整理的軟件,把桌面柵欄式劃分為多個區塊進行管理,按照文件的類型進行自動歸類,效果立竿見影。用了它之后,我的桌面隨時都能保持整潔干凈。

          02.Quicker(快速啟動工具)

          這是一個快速啟動工具,主要功能就是能夠讓你快速啟動其他應用,涵蓋范圍包括電腦中所有的軟件以及網頁,而且啟動什么你都是能自定義設置的,非常方便。

          03.分區助手(電腦磁盤分區)

          電腦C盤難免會有空間不足的情況,如果不及時清理釋放空間,就會嚴重拖累系統運行速度。我們可以考慮用分區助手,來重新調整各個盤符的內存容量,操作簡單,不會損壞原有數據,非常好用。

          04.迅捷壓縮(文件批量壓縮)

          這是一個文件壓縮神器,支持圖片、視頻、PDF、Word、PPT壓縮,做到極致無損壓縮效果,尤其是工作中需要處理很多文件,用它可以批量壓縮,高效辦公。

          05.字由(電腦字體管理)

          這是一款字體應用類軟件,可在線上實現字體管理、預覽、備份與范例展示,也可以把字體下載下來,用于設計logo、海報等,這里的字體都是支持商用的哦。

          06.HBuilder(網頁前端開發)

          這個工具就比較高端了,主要是用于網頁前端開發的,也是目前市面上速度最快的HTML開發工具,強大的代碼助手能幫你快速完成開發,同時還支持最全的語法庫和瀏覽器兼容性數據,妥妥的一個神器!

          最美尾巴:

          以上就是我今天分享的內容,如果大家覺得有用,記得點贊告訴我,我會繼續分享更多優質的內容。

          上面這6個優質的國產軟件,款款精挑細選,讓你的Windows電腦更好用。


          主站蜘蛛池模板: 日韩在线一区二区三区免费视频| 精品无码人妻一区二区免费蜜桃| 国产AV天堂无码一区二区三区| 一区二区传媒有限公司| 亚洲AV无码一区二区二三区软件| 成人区人妻精品一区二区不卡视频 | 最美女人体内射精一区二区| 白丝爆浆18禁一区二区三区| 国产精品成人一区无码| 性色AV一区二区三区无码| 日本国产一区二区三区在线观看| 色窝窝免费一区二区三区 | 91无码人妻精品一区二区三区L| 日韩精品无码一区二区中文字幕| 人妻久久久一区二区三区| 中文字幕一区二区三区在线观看| 国产福利一区二区三区| 国产福利酱国产一区二区| 国产精品亚洲一区二区无码| 无码精品人妻一区二区三区影院| 亚洲国产精品一区二区三区久久| 国产一区二区在线观看app| 国产成人久久精品一区二区三区| 精品日韩亚洲AV无码一区二区三区| 3d动漫精品啪啪一区二区免费| 无码人妻精品一区二区三区99性 | 香蕉在线精品一区二区| 三上悠亚一区二区观看| 亚洲视频一区调教| 日韩精品人妻一区二区三区四区| 国产伦理一区二区三区| 国产一区玩具在线观看| 无码人妻一区二区三区在线视频 | 亚洲欧美日韩一区二区三区在线| 国产一区二区三区在线看片| 久久国产香蕉一区精品| 少妇人妻精品一区二区三区| 在线观看一区二区精品视频| 久久国产精品免费一区| 国产电影一区二区| 精品一区二区三区在线视频观看|