一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

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

PHP教程|ASP.NET教程|JAVA教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|JavaScript|易語言|

服務器之家 - 編程語言 - JAVA教程 - java集合框架線程同步代碼詳解

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

2021-03-09 14:05光與熱 JAVA教程

這篇文章主要介紹了java集合框架線程同步代碼詳解,具有一定借鑒價值,需要的朋友可以參考下。

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

注意,此實現不是同步的。

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

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

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

注意,迭代器的快速失敗行為無法得到保證,因為一般來說,不可能對是否出現不同步并發修改做出任何硬性保證。快速失敗迭代器會盡最大努力拋出ConcurrentModificationException。因此,為提高這類迭代器的正確性而編寫一個依賴于此異常的程序是錯誤的做法:迭代器的快速失敗行為應該僅用于檢測bug。

如上所示,現在建立一個list集合,一個線程對集合進行寫入操作,一個線程進行刪除操作

java" id="highlighter_901534">
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
public class MyArrayList {
    /**
   * 創建一個列表,一個線程進行寫入,一個線程讀取 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);就能對原子操作進行同步了,但是官方api示例為什么要自己手動添加同步呢?

?
1
2
3
4
5
6
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的源代碼

?
1
2
3
4
5
6
SynchronizedCollection(Collection<E> c) {
      if (c==null)
        throw new NullPointerException();
    this.c = c;
      mutex = this;
    }
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
public class MyArrayList {
    /**
   * 創建一個列表,一個線程進行寫入,一個線程讀取 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的同步包裝工具類,還需要對非原子操作用戶還需要手動進行同步

如下所示,加一個線程,對集合進行讀取

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
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();
                    }
                }
            }
        }
    }
}

總結

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

原文鏈接:http://blog.csdn.net/javamoo/article/details/54427486

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 手机看片自拍自自拍日韩免费 | 国产精品免费视频一区一 | www.99精品视频在线播放 | 沉香如屑西瓜视频免费观看完整版 | 亚洲AV久久无码精品九九软件 | 国产乱叫456在线 | 欧洲破处 | cosplay 极品videos | 美女张开双腿让男人捅 | 欧美巨胸 | 国产良心大作白丝精厕 | 国产小视频在线播放 | 国产宅男 | 网友偷自拍原创区 | 亚洲国产高清视频 | 甜蜜调教| 久久久久久久久女黄9999 | 99久久精品免费精品国产 | 成人私人影院www片免费高清 | 免费在线观看网址入口 | 美女脱了内裤打开腿让人羞羞软件 | 我与白丝同桌的故事h文 | 久久热这里只有 精品 | 轻轻操在线视频 | 亚洲国产精品线在线观看 | 果冻传媒天美传媒网址入口 | 国产成人lu在线视频 | 欧美综合在线 | 互换娇妻爽文100系列小说 | 我在厨房摸岳的乳HD在线观看 | 高h射尿| 国产综合欧美日韩视频一区 | 四虎影视黄色 | 无码乱人伦一区二区亚洲一 | 驯服有夫之妇HD中字日本 | 亚洲国产99在线精品一区69堂 | 2020韩国三级理论在线观看 | 99热在线获取最新地址 | 国产成人精品一区二三区2022 | 婷婷色在线观看 | 亚洲六月丁香六月婷婷色伊人 |