整合營銷服務商

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

          免費咨詢熱線:

          List<T>的初始大小

          List<T>的初始大小

          起來真是丟人,干了這么多年.net ,才知道List<T> 初始大小是4,還是調試一段代碼發現的。

          情況是這樣的,給List<T> Add 一個T,結果發現items 里的長度變成了4 ,找了半天原因沒發現代碼有什么問題。就上網查,才發現有這么回事,如果超過了4,長度就會變成8,如下圖

          知道的別嘲笑我啊。

          CopyOnWriteArrayList是一個線程安全集合,原理簡單說就是:在保證線程安全的前提下,犧牲掉寫操作的效率來保證讀操作的高效。所謂CopyOnWrite就是通過復制的方式來完成對數據的修改,在進行修改的時候,復制一個新數組,在新數組上面進行修改操作,這樣就保證了不改變老數組,也就沒有一寫多讀數據不一致的問題了。

          具體的實現來看源碼,JDK 8。

          CopyOnWriteArrayList

          定義

          public class CopyOnWriteArrayList<E>

          implements List<E>, RandomAccess, Cloneable, java.io.Serializable

          在定義上和ArrayList大差不差,不過多解釋,有興趣可以看之前關于ArrayList的文章。

          屬性

          一個是Lock,另一個是一個對象數組。

          /** The lock protecting all mutators *///一把鎖transient final ReentrantLock lock=new ReentrantLock();

          /** The array, accessed only via getArray/setArray. *///一個對象數組,只從方法getArray/setArray處接受值//volatile后面會有專門的文章來說明private volatile transient Object[] array;

          初始化

          CopyOnWriteArrayList的初始化容量是0,分為這樣的幾個步驟。

          //在無參構造方法中會調用setArray方法,參數是一個空的對象數組,然后通過setArray把這個空的數組賦值給屬性arraypublic CopyOnWriteArrayList() {

          setArray(new Object[0]);

          }final void setArray(Object[] a) {

          array=a;

          }

          需要說明的是另一個有參構造方法,參數可以是一個集合

          //按照集合的迭代器返回的順序創建一個包含指定集合元素的列表public CopyOnWriteArrayList(Collection<? extends E> c) {

          //將集合轉為數組

          Object[] elements=c.toArray();//elements不能夠是一個空的對象數組 為什么要if這樣一個條件嘞 因為屬性中需要賦值的是一個對象數組 所以如果if成立執行的就是把原數組變為一個對象數組 如果本身就是對象數組也就不用轉了

          if (elements.getClass() !=Object[].class)

          elements=Arrays.copyOf(elements, elements.length, Object[].class);

          //賦值給屬性

          setArray(elements);

          }

          方法

          add(E e)

          添加一個新元素到list的尾部。

          public boolean add(E e) {

          //鎖 1.5新版本的鎖 已經不用synchronized了

          final ReentrantLock lock=this.lock;

          //加鎖

          lock.lock();

          try {

          //getArray獲取屬性值 就是老數組

          Object[] elements=getArray();

          int len=elements.length;

          //這里是重點 在這里 復制老數組得到了一個長度+1的新數組

          Object[] newElements=Arrays.copyOf(elements, len + 1);

          //添加元素

          newElements[len]=e;

          //用新數組取代老數組

          setArray(newElements);

          return true;

          } finally {

          lock.unlock();

          }

          }

          從add方法中我們可以看到所謂的CopyOnWrite是如何實現的,在需要修改的時候,復制一個新數組,在新數組上修改,修改結束取代老數組,這樣保證了修改操作不影響老數組的正常讀取,另修改操作是加鎖的,也就是說沒有了線程不安全的問題。

          和ArrayList相比較,效率比較低,只添加一個元素的情況下(初始容量均為0),用時是ArrayList的5倍左右,但是隨著CopyOnWriteArrayList中元素的增加,CopyOnWriteArrayList的修改代價將越來越昂貴。

          除了添加其他的修改操作也都是這樣的套路,不做過多解釋,如remove,也是加鎖,復制新數組。

          public E remove(int index) {

          final ReentrantLock lock=this.lock;

          lock.lock();

          try {

          Object[] elements=getArray();

          int len=elements.length;

          E oldValue=get(elements, index);

          int numMoved=len - index - 1;

          if (numMoved==0)

          setArray(Arrays.copyOf(elements, len - 1));

          else {

          // 復制一個新數組

          Object[] newElements=new Object[len - 1];

          System.arraycopy(elements, 0, newElements, 0, index);

          System.arraycopy(elements, index + 1, newElements, index,

          numMoved);

          setArray(newElements);

          }

          return oldValue;

          } finally {

          lock.unlock();

          }

          }

          #####get

          public E get(int index) {

          return get(getArray(), index);

          }//按照下標獲取數組中對應的元素private E get(Object[] a, int index) {

          return (E) a[index];

          }

          讀取的方法就很簡單了,按照下標獲取對應的元素。

          CopyOnWriteArrayList總結

          1. 讀寫分離,我們修改的是新數組,讀取的是老數組,不是一個對象,實現了讀寫分離。這種技術數據庫用的非常多,在高并發下為了緩解數據庫的壓力,即使做了緩存也要對數據庫做讀寫分離,讀的時候使用讀庫,寫的時候使用寫庫,然后讀庫、寫庫之間進行一定的同步,這樣就避免同一個庫上讀、寫的IO操作太多。

          2. 場景:讀操作遠多于修改操作

          架構師視頻資料分享鏈接:

          data:text/html;charset=UTF-8;base64,

          5p625p6E5biI5a2m5Lmg5Lqk5rWB576k5Y+35pivNTc1NzUxODU0Cg==

          復制粘貼在網站即可!

          表標簽

          在html中列表分為無序列表有序列表自定義列表(項目列表)。接下來就看看他們有什么不同吧!

          作用:如果說table標簽是用來顯示數據的,那么列表標簽就是用來進行html頁面布局的。

          • 無序列表

          語法:

          <ul>
          	<li></li>  
          </ul>

          <ul></ul>標簽中只能且必須嵌套<li></li>標簽。li標簽之間沒有先后順序,是并列存在的。li標簽里可以容納文本、數據、圖片、超鏈接等內容。跟table一樣,列表標簽也自帶樣式屬性,但為了代碼統一,我們還是會使用css來設置。

          代碼示例:

          <h2>無序列表:</h2>
              <ul>
                  <li>蘋果</li>
                  <li>橘子</li>
                  <li>香蕉</li>
              </ul>

          運行界面:

          • 有序列表

          語法

          <ol>
           	<li></li> 
           </ol>

          <ol></ol>標簽里面只能嵌套<li></li>標簽,在這里li標簽是有順序的。

          代碼示例:

          <h2>有序列表:</h2>
              <ol>
                  <li>蘋果</li>
                  <li>橘子</li>
                  <li>香蕉</li>
              </ol>

          運行界面:

          • 自定義列表

          語法

          <dl>
          	<dt></dt>
          	<dd></dd>
          </dl>

          <dl></dl>標簽:定義列表

          <dt></dt>標簽:列表標題

          <dd></dd>標簽:列表內容

          一個dd標簽是對dt標簽標題的說明。這兩個標簽中可以包含任何標簽。

          代碼示例:

          <h2>自定義列表:</h2>
              <!-- dl:外層標簽  dt:項目標題  dd:項目內容 -->
              <dl>
                  <dt>水果種類</dt>
                  <dd>蘋果</dd>
                  <dd>橘子</dd>
                  <dd>香蕉</dd>
              </dl>

          運行界面:



          表單標簽

          作用:收集用戶信息。一般用在注冊界面等。

          組成:一個完整的表單中包含表單域(整個填寫界面所有信息)、表單控件(表單元素)和提示信息(表單控件的提示作用)3個部分。

          • 表單域

          表單域:是一個包含表單元素的區域。

          <form>標簽用于定義表單域,實現用戶信息的收集和傳遞。

          作用:將其區域范圍內的信息收集并傳送給服務器。

          語法

          <form action=”url地址” method=”提交方式” name=”表單域名稱”>
          各種表單控件
          </form>

          注:action:url地址,指定接收并處理表單數據的服務器程序的url地址。

          method:用于設置表單數據的提交方式。

          method=”get”:提交數據時,地址欄可查看到數據。數據量少且安全級別不高時使用。

          method=”post”:提交數據時,地址欄數據是加密的。

          name:表單域的名稱。用于區分同一頁面下的不同表單域。

          • 表單控件

          1.input輸入表單元素

          語法:<input type=””>,依據type屬性值不同區分不同控件。

          文本框:<input type=”text”>。單行輸入字段,默認寬度20個字符。輸入的文字可見。

          密碼框:<input type=”password”>。輸入內容默認不可見。

          單選框:<input type=”radio”>,默認情況下選中后無法取消。

          注:為實現多選一狀態,需要將所有的單選框控件具有同一個name名。

          復選框:<input type=”checkbox”>,選中后可以更改可以取消。

          提交按鈕:<input type=”submit”>,默認按鈕中的提示文字是提交,可以通過value值進行更改內容。點擊提交按鈕后會把表單數據發送到服務器。

          重置按鈕:<input type=”reset”>,默認按鈕中的提示文字是重置,可以通過value值進行更改內容。點擊后會清楚表單中的所有數據。

          普通按鈕:<input type=”button”>

          文件域:<input type=”file”>,用來選擇文件,一般適用于文件上傳。

          label標簽:標注標簽,配合input控件一起使用

          作用:綁定表單控件,擴大點擊范圍。

          當點擊label標簽的內容時,系統會自動選中該表單控件。

          代碼示例:

          <h1>label標簽</h1>
              <form>
                  <label for="text">用戶名:</label>
                  <input type="text" name="用戶名" id="text"><br>
                  <label for="password">密碼:</label>
                  <input type="password" id="password"><br>
                  <label for="男">男</label>
                  <input type="radio" name="sex" id="男">
                  <label for="女">女</label>
                  <input type="radio" name="sex" id="女"><br>
              </form>

          運行界面:

          Input控件屬性:

          name:用戶自定義,提示input元素的名稱。給后臺工作人員的提示。

          value:用戶自定義,提示input元素的內容值。給后臺的提示。在文本框控件中會顯示該內容,單選框和復選框則顯示不出來。

          checked:默認選中狀態。主要用于單選按鈕和復選按鈕中。

          maxlength:正整數,規定輸入字段中的字符最大長度。

          input代碼示例:

          <h2>表單標簽</h2>
              <form>
                  用戶名:<input type="text" maxlength="15" value="請輸入用戶名"><br>
                  密  碼:<input type="password"><br>
                  性  別:<input type="radio" name="sex" value="男">男   
          				<input type="radio" name="sex" value="女">女<br>
                  愛  好:<input type="checkbox" name="like" value="swim">游泳 
          				<input type="checkbox" name="like" value="健身">健身 
                  <input type="checkbox" name="like" value="run">跑步<br>
                  <input type="submit">   
                  <input type="reset"><br>
                  <input type="submit" value="注冊">
                  <input type="reset" value="清空"><br>
                  <!-- 后期結合js搭配使用 -->
                  <!-- 按鈕選框在默認情況下是沒有文字內容的,需要添加value值設置文字內容 -->
                  <input type="button" value="獲取短信驗證碼"><br>
                  上傳頭像:<input type="file">
              </form>

          運行界面:

          2.select下拉表單元素

          使用場景:地址選擇、職業分類、學校分類等。

          select標簽:定義下拉列表。

          語法:

          <select>
          	<option></option>  
          </select>

          代碼示例:

          <h1>下拉表單</h1>
              <form>
                  <label for="adress">籍貫:</label>
                  <select name="" id="">
                      <option value="">北京</option>
                      <option value="">河北</option>
                      <option value="">上海</option>
                      <option value="">廣州</option>
                      <option value="">深圳</option>
                  </select>
              </form>

          運行界面:

          3.textrea文本域表單控件

          使用場景:留言、介紹、評論等。

          語法

          <textrea rows=”” cols=””>文本內容</textrea>

          跟文本框控件不同,它是多行文本輸入框,可以自行設定行數以及一行容納多少字數。

          rows=“每行可輸入的字符數”,

          cols=“顯示的行數”。

          這兩個樣式屬性實際開發中大多使用css就可以改變操作。

          代碼示例:

          <h1>文本域表單元素</h1>
              <form action="">
                  <label for="textrea">今日反饋:</label><br>
                  <textarea name="" id="" cols="15" rows="10">今日反饋</textarea>
              </form>

          運行界面:

          關于HTML基礎內容就學習到這里了,明天練習一個綜合案例。對了,現在跟學的是黑馬前端的pink老師發布的基礎視頻,明天做的案例按照老師講解的案例去做。


          主站蜘蛛池模板: 中文字幕在线无码一区| 日本美女一区二区三区| 亚洲AV无码一区二区三区鸳鸯影院 | 国产免费播放一区二区| 少妇精品无码一区二区三区| 3D动漫精品啪啪一区二区下载| 亚洲一区视频在线播放| 国产高清视频一区二区| 亚洲A∨精品一区二区三区下载| 精品乱人伦一区二区三区| 又硬又粗又大一区二区三区视频| 亚洲欧美国产国产一区二区三区| 一区二区三区四区免费视频| 超清无码一区二区三区| 女同一区二区在线观看| 国产成人精品无人区一区| 影音先锋中文无码一区| 亚洲av一综合av一区| 国产日韩精品视频一区二区三区| 亚洲va乱码一区二区三区| 末成年女AV片一区二区| 亚洲国产一区二区a毛片| 国产精品丝袜一区二区三区| 无码人妻一区二区三区免费| 91国在线啪精品一区| 亚洲高清毛片一区二区| 在线观看免费视频一区| 国精产品999一区二区三区有限| 久久久久人妻一区精品果冻| 无码人妻精品一区二区蜜桃网站| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 久久久老熟女一区二区三区| 久久综合九九亚洲一区| 国产在线精品一区在线观看| 亚洲一区二区在线免费观看| 无码精品人妻一区| 亚洲av无码一区二区三区人妖 | 亚洲美女视频一区| 一区二区三区在线观看中文字幕 | 日韩视频一区二区| 亚洲欧美日韩一区二区三区|