java-se - JAVA中多线程使用线程不安全的容器会出现什么情况?
高洛峰
高洛峰 2017-04-17 17:34:29
0
3
691

比如StringBuilder在多线程中使用会导致线程不安全,这个不安全会产生什么后果,是数据不正确或丢失.?

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

répondre à tous(3)
Peter_Zhu

Je vais d'abord vous donner un morceau de code. Vous pouvez l'exécuter vous-même et l'essayer :

public class Main {
    
    public static void main(String[] args) {
        // 用来测试的ArrayList
        List<Object> list = new ArrayList<Object>();

        // 线程数量(1000)
        int threadCount = 1000;

        // 用来让主线程等待threadCount个子线程执行完毕
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);

        // 启动threadCount个子线程
        for (int i = 0; i < threadCount; i++) {
            Thread thread = new Thread(new MyThread(list, countDownLatch));
            thread.start();
        }

        try {
            // 主线程等待所有子线程执行完成,再向下执行
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // List的size
        System.out.println(list.size());
    }

}

class MyThread implements Runnable {
    private List<Object> list;

    private CountDownLatch countDownLatch;

    public MyThread(List<Object> list, CountDownLatch countDownLatch) {
        this.list = list;
        this.countDownLatch = countDownLatch;
    }

    public void run() {
        // 每个线程向List中添加100个元素
        for (int i = 0; i < 100; i++) {
            list.add(new Object());
        }

        // 完成一个子线程
        countDownLatch.countDown();
    }
}

Dans le code ci-dessus, une ArrayList non thread-safe est nouvelle dans le thread principal, puis 1000 threads sont ouverts pour ajouter des éléments à cette ArrayList respectivement. Chaque thread ajoute 100 éléments une fois que tous les threads sont terminés, ceci. devrait être la taille de ArrayList ? Cela devrait être 100 000 ?

Cependant, le résultat réel peut ne pas être de 100 000 ! Le résultat peut être 99946, 99955... C'est pourquoi les collections non thread-safe conduisent à des résultats incorrects dans le cas d'opérations multithread.

Pour des informations spécifiques sur la sécurité des fils de discussion, vous pouvez vous référer à un blog que j'ai écrit : http://xxgblog.com/2013/05/16/java-threa...

Peter_Zhu

Cela entraînera une incohérence des données et les données obtenues peuvent être inexactes. L'impact est entièrement sous le contrôle de votre logique métier

左手右手慢动作

Par exemple, le thread A parcourt une liste

for (int i = 0, max = list.size(); i < max; i++) {
    ...
}

Pendant le processus de parcours, le thread B vient supprimer un élément de la liste. Ensuite, le thread A apparaîtra IndexOutOfBoundsException à la fin du parcours. Pourquoi, car le nombre réel d'éléments est devenu max - 1.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal