午夜无码人妻aⅴ大片色欲张津瑜,国产69久久久欧美黑人A片,色妺妺视频网,久久久久国产综合AV天堂

java高并發(fā)同步容器指的是什么

這篇文章將為大家詳細講解有關(guān)java高并發(fā)同步容器指的是什么,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

創(chuàng)新互聯(lián)建站主營茂南網(wǎng)站建設(shè)的網(wǎng)絡(luò)公司,主營網(wǎng)站建設(shè)方案,重慶APP軟件開發(fā),茂南h5小程序制作搭建,茂南網(wǎng)站營銷推廣歡迎茂南等地區(qū)企業(yè)咨詢

在java中同步容器主要包括兩類:

  • ArrayList -> Vector,Stack;     HashMap -> HashTable(key,value不能為null)

  • Collections.synchronizedXXX(List, Set, Map)

 Vector

Vector實現(xiàn)了List接口,實際上就是一個數(shù)組。與ArrayList非常類似。但是Vector中的所有方法都是使用synchronized方法修飾的方法,進行了同步的措施。因此在多線程環(huán)境下使用ArrayList對象時,如果被多個線程共享使用可以換成同步的Vector,這樣的話線程安全型會更好一些(而不是完全線程安全的)。

@Slf4j
@ThreadSafe
public class VectorExample1 {
    // 請求總數(shù)
    public static int clientTotal = 5000;

    // 同時并發(fā)執(zhí)行的線程數(shù)
    public static int threadTotal = 200;

    private static List<Integer> list = new Vector<>();

    public static void main(String[] args) throws InterruptedException {
        //線程池
        ExecutorService executorService = Executors.newCachedThreadPool();
        //定義信號量
        final Semaphore semaphore = new Semaphore(threadTotal);
        //定義計數(shù)器
        final CountDownLatch countDownLatch = new CountDownLatch(clientTotal);
        for(int i = 0; i < clientTotal; i++) {
            final int count  = i;
            executorService.execute(() ->{
                try {
                    semaphore.acquire();
                    update(count);
                    semaphore.release();
                } catch (InterruptedException e) {

                    log.error("exception", e);
                }
                countDownLatch.countDown();

            });
        }
        countDownLatch.await();
        executorService.shutdown();
        log.info("size:{}",list.size()) ;
    }

    public static void update(int i) {
        list.add(i);
    }

}

這樣輸出的結(jié)果就是預(yù)期的結(jié)果。

為什么說同步容器不是線程安全的?

@NotThreadSafe
public class VectorExample2 {
    private static Vector<Integer> vector = new Vector<>();

    public static void main(String[] args) {
        while (true){
            for (int i = 0;i < 10;i++) {
                vector.add(i);
            }
            Thread thread1 = new Thread(){
                @Override
                public void run() {
                    for (int i = 0;i < vector.size();i++) {
                        vector.remove(i);
                    }
                }
            };
            Thread thread2 = new Thread(){
                @Override
                public void run() {
                    for (int i = 0;i < vector.size();i++) {
                        vector.get(i);
                    }
                }
            };
            thread1.start();
            thread2.start();
        }

    }
}

運行,拋出異常:

Exception in thread "Thread-611" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 5
	at java.util.Vector.get(Vector.java:748)
	at com.vincent.example.syncContainer.VectorExample2$2.run(VectorExample2.java:25)
Exception in thread "Thread-1759" java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 21
	at java.util.Vector.get(Vector.java:748)
	at com.vincent.example.syncContainer.VectorExample2$2.run(VectorExample2.java:25)

原因:get發(fā)生越界肯定是remove方法引起的,vector雖然能保證同一時刻只能有一個線程能訪問他,但是不排除有這種可能:當(dāng)某個線程某個時刻執(zhí)行到int i = 0;i < vector.size()時,vector.size()返回10,i=9;而另外一個線程正好將i=9的vector移除掉了,這時get方法想調(diào)用i=9的元素就會出現(xiàn)數(shù)組越界的異常。

這個例子演示了兩個同步容器的兩個同步方法因為操作順序的差異,在不同線程里面可能會觸發(fā)線程不安全的問題。因此為了保證線程安全,必須在方法調(diào)用端做一些額外的同步措施才可以。在使用同步容器時并不是在所有場合下都是線程安全的。

Stack

Stack中的方法也使用了synchronized修飾了,實際上Stack類繼承了Vector類。

HashTable

HashTable實現(xiàn)了Map接口,與HashMap很相似,但是HashTable進行了同步處理,方法也是使用了synchronized進行了修飾。但是在使用HashTable時一定要注意key和value是不能為null的。

Collections

將新建ArrayList、HashSet、HashMap對象由Collections產(chǎn)生:

private static List<Integer> list = Collections.synchronizedList(new ArrayList<>());
private static Set<Integer> set = Collections.synchronizedSet(new HashSet<>());
private static Map<Integer, Integer> map = Collections.synchronizedMap(new HashMap<>());

在集合遍歷過程中刪除操作

public class VectorExample3 {

    //Exception in thread "main" java.util.ConcurrentModificationException
    private static void test1(Vector<Integer> v1){ //foreach
        for(Integer i: v1){
            if(i.equals(3)){
                v1.remove(i);
            }
        }
    }
    //Exception in thread "main" java.util.ConcurrentModificationException
    private static void test2(Vector<Integer> v1){ //iterator
        Iterator<Integer> integerIterator = v1.iterator();
        while (integerIterator.hasNext()) {
            Integer i = integerIterator.next();
            if(i.equals(3)){
                v1.remove(i);
            }
        }
    }
    // success
    private static void test3(Vector<Integer> v1){
        for(int i = 0; i < v1.size(); i++) {
            if(v1.equals(3)){
                v1.remove(i);
            }
        }
    }

    public static void main(String[] args) {
        Vector<Integer> vector = new Vector<>();
        vector.add(1);
        vector.add(2);
        vector.add(3);
        test1(vector);
    }
}

如果使用了Foreach或者迭代器來循環(huán)我們的集合時,盡量不要在循環(huán)中做集合的刪除操作,如果要做remove操作時,建議在遍歷的過程中發(fā)現(xiàn)需要刪除的值然后做一個標(biāo)記,在遍歷結(jié)束后在執(zhí)行相應(yīng)的remove操作。在多線程情況下出現(xiàn)異常的情況會更大。

關(guān)于java高并發(fā)同步容器指的是什么就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

當(dāng)前題目:java高并發(fā)同步容器指的是什么
網(wǎng)站地址:http://www.ekvhdxd.cn/article42/jsjdec.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供小程序開發(fā)、網(wǎng)站制作、微信小程序、網(wǎng)站收錄、移動網(wǎng)站建設(shè)、網(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)

h5響應(yīng)式網(wǎng)站建設(shè)