程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 非阻塞線程安全列表——ConcurrentLinkedDeque應用舉例

非阻塞線程安全列表——ConcurrentLinkedDeque應用舉例

編輯:關於C++

在java中,最常用的數據結構可能是列表。有數目不詳的元素列表,你可以添加、閱讀、或刪除任何位置的元素。此外,並發列表允許不同的線程列表中添加或刪除元素時不產生任何數據不一致。非阻塞列表提供如下操作,如果操作不能立即完成,列出拋出異常或者返回一個null值。Java 7中引入了ConcurrentLinkedDeque類,它實現了一個非阻塞並發列表,在本教程中,我們將學習使用這個類。

 

在這個例子中,我們將實現一個示例使用以下兩個不同的任務:

一個將大量數據添加到一個列表中
一個大量地從同樣的列表中刪除數據
讓我們為每個任務創建的線程:

 

package com.howtodoinjava.demo.multithreading.concurrentLinkedDequeExample;
 
import java.util.concurrent.ConcurrentLinkedDeque;
 
public class AddTask implements Runnable {
 
    private ConcurrentLinkedDeque list;
 
    public AddTask(ConcurrentLinkedDeque list) {
        this.list = list;
    }
 
    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        for (int i = 0; i < 10000; i++) {
            list.add(name + : Element  + i);
        }
    }
}

和:

package com.howtodoinjava.demo.multithreading.concurrentLinkedDequeExample; import java.util.concurrent.ConcurrentLinkedDeque; public class RemoveTask implements Runnable { private ConcurrentLinkedDeque list; public RemoveTask(ConcurrentLinkedDeque list) { this.list = list; } @Override public void run() { for (int i = 0; i < 5000; i++) { list.pollFirst(); list.pollLast(); } } }

 

現在,讓我們創建100個線程將數據添加到列表和100個線程從列表刪除數據。如果真的是線程安全的和非阻塞,它會幾乎立即給你最終結果。此外,列表大小最終將是零。

package com.howtodoinjava.demo.multithreading.concurrentLinkedDequeExample;
 
import java.util.concurrent.ConcurrentLinkedDeque;
 
public class Main {
    public static void main(String[] args)
    {
        ConcurrentLinkedDeque list = new ConcurrentLinkedDeque<>();
        Thread threads[] = new Thread[100];
 
        for (int i = 0; i < threads.length; i++) {
            AddTask task = new AddTask(list);
            threads[i] = new Thread(task);
            threads[i].start();
        }
        System.out.printf(Main: %d AddTask threads have been launched
, threads.length);
 
        for (int i = 0; i < threads.length; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.printf(Main: Size of the List: %d
, list.size());
 
        for (int i = 0; i < threads.length; i++) {
            RemoveTask task = new RemoveTask(list);
            threads[i] = new Thread(task);
            threads[i].start();
        }
        System.out.printf(Main: %d RemoveTask threads have been launched
, threads.length);
 
        for (int i = 0; i < threads.length; i++) {
            try {
                threads[i].join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.printf(Main: Size of the List: %d
, list.size());
    }
}
 
Output:
 
Main: 100 AddTask threads have been launched
Main: Size of the List: 1000000
Main: 100 RemoveTask threads have been launched
Main: Size of the List: 0

 

讓我們看看它如何工作:

  1. 首先,你有100執行 AddTask將元素添加到任務列表。每一個這些任務插入10000個元素的列表使用 add()方法。這種方法增加了新元素列表的最後。當所有這些任務已經完成了,你寫在控制台的數量列表的元素。這時,有1000000個元素的列表。
  2. 然後,你有100執行 RemoveTask任務來從列表中刪除元素。每一個這些任務刪除使用10000個元素的列表 pollFirst()pollLast()方法。pollFirst()方法返回和刪除列表的第一個元素和pollLast()方法返回和刪除最後一個元素的列表。如果列表為空,這些方法返回一個null值。當所有這些任務已經完成了,你寫在控制台的數量列表的元素。這時,有零元素列表。
  3. 編寫列表的元素的數量,你使用了 size()方法。你必須考慮,這種方法可以返回一個值,並不是真實的,特別是如果你使用它當線程列表中添加或刪除數據。計數的方法遍歷整個列表的元素和內容列表可以改變這個操作。只有在你使用它們時沒有任何線程修改列表,你可以保證返回的結果是正確的。

    請注意, ConcurrentLinkedDeque類提供了更多的方法來獲取元素列表形式:

    • getFirst() getLast():這些方法返回分別從列表中第一個和最後一個元素。他們不會從列表中刪除返回的元素。如果列表是空的,這些方法拋出一個 NoSuchElementExcpetion例外。
    • peek(), peekFirst(), peekLast():這些方法返回列表的第一個和最後一個元素。他們不會從列表中刪除返回的元素。如果列表為空,這些方法返回一個null值。
    • remove(), removeFirst(), removeLast():這些方法返回列表的第一個和最後一個元素。他們從列表中移除返回的元素。如果列表是空的,這些方法拋出一個 NoSuchElementException例外。
    • 一個 ConcurrentLinkedDeque是一個合適的選擇,許多線程共享訪問公共集合。
    • 像大多數其他並發集合實現,這個類不允許null元素的使用。
    • 迭代器是弱一致的,返回元素反映在一些點或雙端隊列的狀態,因為迭代器的創建。他們不把ConcurrentModificationException與其他操作,可以同時進行。

       

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved