java集合框架線程同步代碼詳解

List接口的大小可變數(shù)組的實現(xiàn)。實現(xiàn)了所有可選列表操作,并允許包括null在內(nèi)的所有元素。除了實現(xiàn)List接口外,此類還提供一些方法來操作內(nèi)部用來存儲列表的數(shù)組的大小。(此類大致上等同于Vector類,除了此類是不同步的。)size、isEmpty、get、set、iterator和listIterator操作都以固定時間運行。add操作以分?jǐn)偟墓潭〞r間運行,也就是說,添加n個元素需要O(n)時間。其他所有操作都以線性時間運行(大體上講)。與用于LinkedList實現(xiàn)的常數(shù)因子相比,此實現(xiàn)的常數(shù)因子較低。每個ArrayList實例都有一個容量。該容量是指用來存儲列表元素的數(shù)組的大小。它總是至少等于列表的大小。隨著向ArrayList中不斷添加元素,其容量也自動增長。并未指定增長策略的細(xì)節(jié),因為這不只是添加元素會帶來分?jǐn)偣潭〞r間開銷那樣簡單。在添加大量元素前,應(yīng)用程序可以使用ensureCapacity操作來增加ArrayList實例的容量。這可以減少遞增式再分配的數(shù)量。

創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比洮北網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式洮北網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋洮北地區(qū)。費用合理售后完善,10年實體公司更值得信賴。

注意,此實現(xiàn)不是同步的。

如果多個線程同時訪問一個ArrayList實例,而其中至少一個線程從結(jié)構(gòu)上修改了列表,那么它必須保持外部同步。(結(jié)構(gòu)上的修改是指任何添加或刪除一個或多個元素的操作,或者顯式調(diào)整底層數(shù)組的大?。粌H僅設(shè)置元素的值不是結(jié)構(gòu)上的修改。)這一般通過對自然封裝該列表的對象進(jìn)行同步操作來完成。如果不存在這樣的對象,則應(yīng)該使用Collections.synchronizedList方法將該列表“包裝”起來。這最好在創(chuàng)建時完成,以防止意外對列表進(jìn)行不同步的訪問:

Listlist=Collections.synchronizedList(newArrayList(...));

此類的iterator和listIterator方法返回的迭代器是快速失敗的:在創(chuàng)建迭代器之后,除非通過迭代器自身的remove或add方法從結(jié)構(gòu)上對列表進(jìn)行修改,否則在任何時間以任何方式對列表進(jìn)行修改,迭代器都會拋出ConcurrentModificationException。因此,面對并發(fā)的修改,迭代器很快就會完全失敗,而不是冒著在將來某個不確定時間發(fā)生任意不確定行為的風(fēng)險。

注意,迭代器的快速失敗行為無法得到保證,因為一般來說,不可能對是否出現(xiàn)不同步并發(fā)修改做出任何硬性保證??焖偈〉鲿M最大努力拋出ConcurrentModificationException。因此,為提高這類迭代器的正確性而編寫一個依賴于此異常的程序是錯誤的做法:迭代器的快速失敗行為應(yīng)該僅用于檢測bug。

如上所示,現(xiàn)在建立一個list集合,一個線程對集合進(jìn)行寫入操作,一個線程進(jìn)行刪除操作

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
public class MyArrayList {
	/** 
   * 創(chuàng)建一個列表,一個線程進(jìn)行寫入,一個線程讀取 iterator 和 listIterator 方法返回的迭代器是快速失敗的 
   */
	public void readWrite() {
		List<Integer> nums = new ArrayList<Integer>();
		List<Integer> synNums = Collections.synchronizedList(nums);
		//啟動寫入線程 
		new WriteListThread(synNums).start();
		//啟動刪除線程 
		new DeleteListThread(synNums).start();
	}
	public static void main(String[] args) {
		new MyArrayList().readWrite();
	}
}
class WriteListThread extends Thread {
	private List<Integer> nums;
	public WriteListThread(List<Integer> nums) {
		super(“WriteListThread”);
		this.nums = nums;
	}
	// 不停寫入元素1 
	public void run() {
		while (true) {
			nums.add(new Random().nextint(1000));
			System.out.println(Thread.currentThread().getName());
		}
	}
}
class DeleteListThread extends Thread {
	private List<Integer> nums;
	public DeleteListThread(List<Integer> nums) {
		super(“DeleteListThread”);
		this.nums = nums;
	}
	// 刪除第一個元素 
	public void run() {
		while (true) {
			try{
				System.out.println(Thread.currentThread().getName()+”:”+nums.remove(0));
			}
			catch(Exception e){
				continue ;
			}
		}
	}
}

通過List<Integer>synNums=Collections.synchronizedList(nums);就能對原子操作進(jìn)行同步了,但是官方api示例為什么要自己手動添加同步呢?

List list = Collections.synchronizedList(new ArrayList()); 
 synchronized(list) { 
   Iterator i = list.iterator(); // Must be in synchronized block 
   while (i.hasNext()) 
     foo(i.next()); 
 } 

查看Collections.synchronizedList的源代碼

SynchronizedCollection(Collection<E> c) { 
      if (c==null) 
        throw new NullPointerException(); 
    this.c = c; 
      mutex = this; 
    } 
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
public class MyArrayList {
	/** 
   * 創(chuàng)建一個列表,一個線程進(jìn)行寫入,一個線程讀取 iterator 和 listIterator 方法返回的迭代器是快速失敗的 
   */
	public void readWrite() {
		List<Integer> nums = new ArrayList<Integer>();
		List<Integer> synNums = Collections.synchronizedList(nums);
		//啟動寫入線程 
		new WriteListThread(synNums).start();
		//啟動刪除線程 
		new DeleteListThread(synNums).start();
	}
	public static void main(String[] args) {
		new MyArrayList().readWrite();
	}
}
class WriteListThread extends Thread {
	private List<Integer> nums;
	public WriteListThread(List<Integer> nums) {
		super("WriteListThread");
		this.nums = nums;
	}
	// 不停寫入元素1 
	public void run() {
		while (true) {
			nums.add(new Random().nextint(1000));
			System.out.println(Thread.currentThread().getName());
		}
	}
}
class DeleteListThread extends Thread {
	private List<Integer> nums;
	public DeleteListThread(List<Integer> nums) {
		super("DeleteListThread");
		this.nums = nums;
	}
	// 刪除第一個元素 
	public void run() {
		while (true) {
			try{
				System.out.println(Thread.currentThread().getName()+":"+nums.remove(0));
			}
			catch(Exception e){
				continue ;
			}
		}
	}
}

可見對于集合同步操作,使用Collections的同步包裝工具類,還需要對非原子操作用戶還需要手動進(jìn)行同步

如下所示,加一個線程,對集合進(jìn)行讀取

class ReadListThread extends Thread {
	private List<Integer> nums;
	public ReadListThread(List<Integer> nums) {
		super(“ReadListThread”);
		this.nums = nums;
	}
	// 不停讀取元素,非原子操作,則需要手動加上鎖 
	public void run() {
		while (true) {
			//休眠,將鎖交給其他線程 
			try {
				Thread.sleep(1000);
			}
			catch (InterruptedException e1) {
				e1.printStackTrace();
			}
			synchronized (nums) {
				if (nums.size() > 100) {
					Iterator<Integer> iter = nums.iterator();
					while (iter.hasNext()) {
						System.out.println(Thread.currentThread().getName() 
						                + ”:” + iter.next());
						;
					}
				} else{
					try {
						nums.wait(1000);
					}
					catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		}
	}
}

總結(jié)

以上就是本文關(guān)于java集合框架線程同步代碼詳解的全部內(nèi)容,希望對大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站其他相關(guān)專題,如有不足之處,歡迎留言指出。感謝朋友們對本站的支持!

文章題目:java集合框架線程同步代碼詳解
地址分享:http://muchs.cn/article14/ghjode.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制開發(fā)、全網(wǎng)營銷推廣網(wǎng)站收錄、網(wǎng)頁設(shè)計公司、靜態(tài)網(wǎng)站品牌網(wǎng)站制作

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運營