国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

JUC并發(fā)編程——集合類不安全及Callable(基于狂神說(shuō)的學(xué)習(xí)筆記)

這篇具有很好參考價(jià)值的文章主要介紹了JUC并發(fā)編程——集合類不安全及Callable(基于狂神說(shuō)的學(xué)習(xí)筆記)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

集合類不安全

List不安全

package unsafe;

import PC.A;

import java.util.*;
import java.util.concurrent.CopyOnWriteArrayList;

// ArrayList線程不安全,在多線程下使用ArrayList會(huì)報(bào)錯(cuò):
// java.util.ConcurrentModificationException 并發(fā)修改異常
public class ListTest {

    public static void main(String[] args) {
        // 并發(fā)下ArrayList 不安全
        /**
         * 解決方案:
         * 1、List<String> list= new Vector<>();
         * 實(shí)際上,Vector在jdk1.0就已經(jīng)出來(lái)了,ArrayList在jdk1.2才出來(lái)
         * Vector實(shí)際上就是在add時(shí)將方法synchronized鎖起來(lái)了
         * 2、List<String> list = Collections.synchronizedList(new ArrayList<>());// 通過(guò)工具類將其轉(zhuǎn)換乘synchronized保證線程安全
         * 3、List<String> list = new CopyOnWriteArrayList<>();
         */
        //List<String> list = new ArrayList<>();
        //List<String> list = Collections.synchronizedList(new ArrayList<>());
        List<String> list = new CopyOnWriteArrayList<>();
        // CopyOnWrite 寫(xiě)入時(shí)復(fù)制 COW 計(jì)算機(jī)程序設(shè)計(jì)領(lǐng)域的一種優(yōu)化策略
        // 多個(gè)線程調(diào)用的時(shí)候 list,讀取的時(shí)候,固定的,寫(xiě)入的時(shí)候可能會(huì)覆蓋
        // 在寫(xiě)入的時(shí)候避免覆蓋,造成數(shù)據(jù)問(wèn)題
        // CopyOnWriteArrayList比Vector的優(yōu)勢(shì)在于,copyOnWriteArrayList在并發(fā)下效率要比vector更高,因?yàn)镃opyOnWriteArrayList使用的是寫(xiě)時(shí)復(fù)制策略,而非使用synchronized鎖
        for (int i = 1; i <= 10; i++) {
            new Thread(()->{
                list.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(list);
            },String.valueOf(i)).start();
        }
    }
}

CopyOnWriteArrayList與vector對(duì)比,以下來(lái)自CSDN智能助手的回答:

Java中的CopyOnWriteArrayList和Vector都是線程安全的動(dòng)態(tài)數(shù)組,可以在多線程環(huán)境下使用。

CopyOnWriteArrayList使用了一種特殊的寫(xiě)時(shí)復(fù)制機(jī)制,它在對(duì)數(shù)組進(jìn)行修改時(shí),會(huì)創(chuàng)建一個(gè)新的副本,而不是直接在原數(shù)組上進(jìn)行修改。這樣可以確保在多線程并發(fā)修改時(shí)不會(huì)發(fā)生問(wèn)題。然而,由于每次修改都需要?jiǎng)?chuàng)建一個(gè)新的副本,所以在寫(xiě)入操作頻繁的情況下,CopyOnWriteArrayList的性能可能會(huì)比較低。

Vector是一個(gè)同步的動(dòng)態(tài)數(shù)組,它使用了synchronized關(guān)鍵字來(lái)保證多線程安全。當(dāng)多個(gè)線程同時(shí)修改Vector時(shí),每個(gè)線程會(huì)依次獲得鎖,并按順序執(zhí)行相應(yīng)的修改操作。雖然Vector具有線程安全性,但在高并發(fā)情況下,由于需要頻繁的獲取鎖和釋放鎖,可能會(huì)導(dǎo)致性能下降。

因此,如果在多線程環(huán)境下需要頻繁進(jìn)行讀操作,而寫(xiě)操作較少的情況下,CopyOnWriteArrayList可能會(huì)更適合。而如果需要頻繁進(jìn)行寫(xiě)操作或者對(duì)線程安全性要求不是非常高,可以考慮使用Vector。

而后筆者在IDEA中翻閱關(guān)于CopyOnWriteArralyList的add()方法源碼發(fā)現(xiàn),它還是使用synchronized關(guān)鍵字,源碼如下:

/**
 * Appends the specified element to the end of this list.
 *
 * @param e element to be appended to this list
 * @return {@code true} (as specified by {@link Collection#add})
 */
public boolean add(E e) {
    synchronized (lock) {
        Object[] es = getArray();
        int len = es.length;
        es = Arrays.copyOf(es, len + 1);
        es[len] = e;
        setArray(es);
        return true;
    }
}

然后筆者去查了文心一言的回答,得到的答案依然是CopyOnWriteArralyList沒(méi)有使用synchronized鎖,回答如下:

CopyOnWriteArrayListadd()方法不是使用synchronized關(guān)鍵字來(lái)實(shí)現(xiàn)的。實(shí)際上,CopyOnWriteArrayListadd()方法內(nèi)部使用的是一種稱為"寫(xiě)時(shí)復(fù)制"(Copy-on-Write)的技術(shù)。

在寫(xiě)時(shí)復(fù)制策略中,數(shù)據(jù)結(jié)構(gòu)被修改時(shí),修改操作會(huì)在一個(gè)新的副本上進(jìn)行,而不是直接在原始數(shù)據(jù)上進(jìn)行。這樣,讀取操作可以在原始數(shù)據(jù)上進(jìn)行,而不需要等待寫(xiě)入操作完成。寫(xiě)入操作完成后,原始數(shù)據(jù)會(huì)被丟棄,新的副本會(huì)成為新的原始數(shù)據(jù)。

CopyOnWriteArrayList中,當(dāng)調(diào)用add()方法時(shí),它會(huì)創(chuàng)建一個(gè)新的數(shù)組副本,將新元素添加到該副本中,然后將原始數(shù)組引用指向新數(shù)組。由于創(chuàng)建新數(shù)組和修改操作是在一個(gè)單獨(dú)的寫(xiě)鎖上進(jìn)行的,因此多個(gè)線程可以同時(shí)讀取原始數(shù)組,而不會(huì)看到正在進(jìn)行的寫(xiě)入操作。

因此,CopyOnWriteArrayListadd()方法并沒(méi)有使用synchronized關(guān)鍵字來(lái)實(shí)現(xiàn)線程安全。而是使用寫(xiě)時(shí)復(fù)制技術(shù)和讀寫(xiě)鎖來(lái)實(shí)現(xiàn)更細(xì)粒度的并發(fā)控制。

因此,copyWriteArrayList在并發(fā)下是否效率更高有待商榷

Set不安全

package unsafe;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArraySet;

public class SetTest {

    public static void main(String[] args) {

       // Set<String> set = new HashSet<>(); // 線程不安全
       // Set<String> set = Collections.synchronizedSet(new HashSet<>());// 通過(guò)工具類將其轉(zhuǎn)換成synchronized保證線程安全
        Set<String> set = new CopyOnWriteArraySet<>();// 通過(guò)讀寫(xiě)復(fù)制策略保證線程安全

        for (int i = 1; i <= 20; i++) {
            new Thread(()->{
                set.add(UUID.randomUUID().toString().substring(0,5));
                System.out.println(set);
            },String.valueOf(i)).start();

        }
    }
}

hashSet的底層是什么?

HashSet本質(zhì)上就是HashMap,源碼:

/**
 * Constructs a new, empty set; the backing {@code HashMap} instance has
 * default initial capacity (16) and load factor (0.75).
 */
public HashSet() {
    map = new HashMap<>();
}

// add() set本質(zhì)就是map key是無(wú)法重復(fù)的
    /**
     * Adds the specified element to this set if it is not already present.
     * More formally, adds the specified element {@code e} to this set if
     * this set contains no element {@code e2} such that
     * {@code Objects.equals(e, e2)}.
     * If this set already contains the element, the call leaves the set
     * unchanged and returns {@code false}.
     *
     * @param e element to be added to this set
     * @return {@code true} if this set did not already contain the specified
     * element
     */
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
// PRESENT 是一個(gè)常量
    // Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

HashMap不安全

ConcurrentHashMap<>()

package unsafe;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class MapTest {

    public static void main(String[] args) {
        // 線程不安全
        // map 是下面這條語(yǔ)句這樣用的碼?----> 不是,工作中不用HashMap
        // 默認(rèn)等價(jià)于什么? -----> Map<String, String> map = new HashMap<>(16,0.75);
        // Map<String, String> map = new HashMap<>();

        // 線程安全
        Map<String,String> map = new ConcurrentHashMap<>();
        for (int i = 1; i <= 30; i++) {
            new Thread(()->{
                map.put(Thread.currentThread().getName(), UUID.randomUUID().toString().substring(0,5));
                System.out.println(map);
            },String.valueOf(i)).start();
        }

    }
}

Callable

特點(diǎn)

1、可以有返回值

2、可以拋出異常

3、方法不同,run() / call()

package callable;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class CallableTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // new Thread(new Runnable()).start();
        // 等價(jià)于 new Thread(new FutureTask<V>()).start();
        // new Thread(new FutureTask<V>(Callable)).start();--->FutureTask<V>的構(gòu)造器為Callable
        new Thread().start();// 怎么啟動(dòng)callable
        MyThread thread = new MyThread();
        FutureTask futureTask = new FutureTask(thread);// 適配類
        new Thread(futureTask,"A").start();
        new Thread(futureTask,"B").start();// 結(jié)果會(huì)被緩存,提高效率
        // 這個(gè)get方法可能會(huì)產(chǎn)生阻塞,加入call()是一個(gè)耗時(shí)操作,則get需要等待返回值
        // 一般將get放在最后,或者使用異步通信來(lái)處理
        Integer o = (Integer) futureTask.get();// 獲取Callable的返回結(jié)果
        System.out.println(o);

    }
}

class MyThread implements Callable<Integer> {


    @Override
    public Integer call() throws Exception {
        System.out.println("call()");
        return 1024;
    }
}

細(xì)節(jié):

1、 有緩存

2、結(jié)果可能需要等待,會(huì)阻塞文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-724644.html

到了這里,關(guān)于JUC并發(fā)編程——集合類不安全及Callable(基于狂神說(shuō)的學(xué)習(xí)筆記)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Java集合類不安全示例】

    提示:以下是本篇文章正文內(nèi)容,下面案例可供參考 代碼如下(示例): 輸出結(jié)果 Exception in thread “Thread-1” Exception in thread “Thread-0” Exception in thread “Thread-4” Exception in thread “Thread-25” Exception in thread “Thread-23” Exception in thread “Thread-17” Exception in thread “Thread-18”

    2024年02月03日
    瀏覽(16)
  • 【并發(fā)編程】JUC并發(fā)編程(徹底搞懂JUC)

    【并發(fā)編程】JUC并發(fā)編程(徹底搞懂JUC)

    如果你對(duì)多線程沒(méi)什么了解,那么從入門模塊開(kāi)始。 如果你已經(jīng)入門了多線程(知道基礎(chǔ)的線程創(chuàng)建、死鎖、synchronized、lock等),那么從juc模塊開(kāi)始。 新手學(xué)技術(shù)、老手學(xué)體系,高手學(xué)格局。 JUC實(shí)際上就是我們對(duì)于jdk中java.util .concurrent 工具包的簡(jiǎn)稱 ,其結(jié)構(gòu)如下: 這個(gè)包

    2024年02月20日
    瀏覽(19)
  • Java并發(fā)編程:Callable、Future和FutureTask

    在前面的文章中我們講述了創(chuàng)建線程的 2 種方式,一種是直接繼承 Thread ,另外一種就是實(shí)現(xiàn) Runnable 接口。 這 2 種方式都有一個(gè)缺陷就是:在執(zhí)行完任務(wù)之后無(wú)法獲取執(zhí)行結(jié)果。 如果需要獲取執(zhí)行結(jié)果,就必須通過(guò)共享變量或者使用線程通信的方式來(lái)達(dá)到效果,這樣使用起

    2024年02月13日
    瀏覽(26)
  • 并發(fā)編程-JUC-原子類

    并發(fā)編程-JUC-原子類

    JUC 整體概覽 原子類 基本類型-使用原子的方式更新基本類型 AtomicInteger:整形原子類 AtomicLong:長(zhǎng)整型原子類 AtomicBoolean :布爾型原子類 引用類型 AtomicReference:引用類型原子類 AtomicStampedReference:原子更新引用類型里的字段原子類 AtomicMarkableReference :原子更新帶有標(biāo)記位的引

    2024年02月21日
    瀏覽(23)
  • JUC并發(fā)編程(二)

    JUC并發(fā)編程(二)

    JUC并發(fā)編程(續(xù)) 接上一篇筆記:https://blog.csdn.net/weixin_44780078/article/details/130694996 五、Java內(nèi)存模型 JMM 即 Java Memory Model,它定義了主存、工作內(nèi)存抽象概念,底層對(duì)應(yīng)著CPU寄存器、緩存、硬件內(nèi)存、CPU 指令優(yōu)化等。 JMM 體現(xiàn)在以下幾個(gè)方面: 原子性:保證指令不會(huì)受到線程

    2024年02月05日
    瀏覽(27)
  • 第九章 JUC并發(fā)編程

    第九章 JUC并發(fā)編程

    http://t.csdn.cn/UgzQi 使用 AQS加 Lock 接口實(shí)現(xiàn)簡(jiǎn)單的不可重入鎖 早期程序員會(huì)自己通過(guò)一種同步器去實(shí)現(xiàn)另一種相近的同步器,例如用可重入鎖去實(shí)現(xiàn)信號(hào)量,或反之。這顯然不夠優(yōu)雅,于是在 JSR166(java 規(guī)范提案)中創(chuàng)建了 AQS,提供了這種通用的同步器機(jī)制。 AQS 要實(shí)現(xiàn)的功能

    2023年04月08日
    瀏覽(21)
  • 【JUC并發(fā)編程】

    【JUC并發(fā)編程】

    本筆記內(nèi)容為狂神說(shuō)JUC并發(fā)編程部分 目錄 一、什么是JUC 二、線程和進(jìn)程 1、概述? 2、并發(fā)、并行 3、線程有幾個(gè)狀態(tài)? 4、wait/sleep 區(qū)別 三、Lock鎖(重點(diǎn))? 四、生產(chǎn)者和消費(fèi)者問(wèn)題 五、八鎖現(xiàn)象 六、集合類不安全? 七、Callable ( 簡(jiǎn)單 ) 八、常用的輔助類(必會(huì)) 1、CountDown

    2024年02月09日
    瀏覽(11)
  • JUC并發(fā)編程14 | ThreadLocal

    JUC并發(fā)編程14 | ThreadLocal

    尚硅谷JUC并發(fā)編程(100-111) ThreadLocal是什么? ThreadLocal 提供 線程局部變量 。這些變量與正常的變量有所不同,因?yàn)槊恳粋€(gè)線程在訪問(wèn)ThreadLocal實(shí)例的時(shí)候(通過(guò)其get或set方法)都有自己的、獨(dú)立初始化的變量副本。ThreadLocal實(shí)例通常是類中的私有靜態(tài)字段,使用它的目的是

    2024年02月04日
    瀏覽(23)
  • JUC 高并發(fā)編程基礎(chǔ)篇

    JUC 高并發(fā)編程基礎(chǔ)篇

    ? 1、什么是 JUC ? 2、Lock 接口 ? 3、線程間通信 ? 4、集合的線程安全 ? 5、多線程鎖 ? 6、Callable 接口 ? 7、JUC 三大輔助類: CountDownLatch CyclicBarrier Semaphore ? 8、讀寫(xiě)鎖: ReentrantReadWriteLock ? 9、阻塞隊(duì)列 ? 10、ThreadPool 線程池 ? 11、Fork/Join 框架 ? 12、CompletableFuture 1 什么

    2024年02月07日
    瀏覽(20)
  • JUC并發(fā)編程之原子類

    目錄 1. 什么是原子操作 1.1?原子類的作用 1.2?原子類的常見(jiàn)操作 原子類的使用注意事項(xiàng) 并發(fā)編程是現(xiàn)代計(jì)算機(jī)應(yīng)用中不可或缺的一部分,而在并發(fā)編程中,處理共享資源的并發(fā)訪問(wèn)是一個(gè)重要的問(wèn)題。為了避免多線程訪問(wèn)共享資源時(shí)出現(xiàn)競(jìng)態(tài)條件(Race Condition)等問(wèn)題,J

    2024年02月13日
    瀏覽(18)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包