【深入浅出多线程系列十】:只有从不同案例中,才能深刻体会多线程的不安全,从而才能更好的解决!(案例+代码示例)

在学习Java的道路上,是否路过多线程时总让你很迷惘;很不巧,我也是,而使我们感到很迷惘主要原因都源于没有对概念的深深的理解和实践。所以我决定漫步Java多线程,同你一起会会多线程。

多线程系列

多线程系列一:理解多线程在于深深地理解了多任务、进程、多线程、线程
多线程系列二:手撕多线程,从会三种创建多线程方式开始:除了常见的两种,你是否了解Callable接口方式?
多线程系列三:初遇并发问题:从一个小故事开始,从一行行代码开始
多线程系列四:停止多线程,你不会还以为是用stop和destroy吧?
多线程系列五:多线程为何要使用休眠?
多线程系列六:线程礼让与强制执行
多线程系列七:纯手绘图解多线程状态+代码示例,就问你怕了吗?
多线程系列八:多线程的优先级
多线程系列九:守护线程
多线程系列十:通过案例体会多线程的不安全(案例+代码示例)

在多线程系列三中,就曾碰到过并发问题,也就是我们线程的不安全问题(没有看过的小伙伴可以看看)

多线程系列三:初遇并发问题:从一个小故事开始,从一行行代码开始

当然不看也没关系

再次举几个栗子体会一下线程不安全

有必要提醒一下,这一章还是不打算教你如何解决线程安全

没错,是这么直白,多线程系列三中说后续章节会讲,但是不是这一章

因为解决不管是多线程系列三还是这一章的的多线程安全问题,实在是很简单,加个synchronized就能解决,我想这个有点基础的小伙伴都是知道的

但是看似越简单的synchronized,背后也会越复杂

如果只是单纯碰到线程问题就往上加,那么离底层的原理和机制就会越遥远;不仅碰到不同的小问题解决得吃力,大问题我想就不用说了。

只有从深刻的线程中体会到安全问题,才能更透彻领悟线程同步原理和机制。

public class ThreadDemo implements Runnable{

    private Integer ticket = 2;
    private boolean sign = true;

    @Override
    public void run() {
        while (sign) {
            try {
                buyTickets();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    private void buyTickets() throws InterruptedException {
        if (ticket <= 0) {
            sign = false;
            return;
        }
        Thread.sleep(1000);
        System.out.println(Thread.currentThread().getName()+"抢到了第"+ticket--+"张票");
    }

    public static void main(String[] args) {
        ThreadDemo thread = new ThreadDemo();
        new Thread(thread,"小白").start();
        new Thread(thread,"小蓝").start();
        new Thread(thread,"一颗剽悍的种子").start();
    }
}

【深入浅出多线程系列十】:只有从不同案例中,才能深刻体会多线程的不安全,从而才能更好的解决!(案例+代码示例)_第1张图片

public class ThreadDemo implements Runnable{
    @Override
    public void run() {
        ArrayList<String> list = new ArrayList<String>();
        list.add(Thread.currentThread().getName());
        System.out.println(list);
    }
    public static void main(String[] args) {
        ThreadDemo threadDemo = new ThreadDemo();
        for (int i = 0; i < 10000; i++) {
            new Thread(threadDemo).start();
        }
    }
}

【深入浅出多线程系列十】:只有从不同案例中,才能深刻体会多线程的不安全,从而才能更好的解决!(案例+代码示例)_第2张图片
集合在线程下

集合在只有一个主线程下

当然是安全滴

public class ThreadDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        for (int i = 0; i < 10000; i++) {
            list.add(Thread.currentThread().getName());
        }
        System.out.println(list.size());
    }
}

运行结果

在这里插入图片描述
在多线程下

public class ThreadDemo {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<String>();
        for (int i = 0; i < 10000; i++) {
            new Thread(() -> {
                list.add(Thread.currentThread().getName());
            }).start();
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(list.size());
    }
}

运行结果

可以看到集合的长度添加的数量并不是我们预期的长度。

而是可能会出现覆盖

在多线程下集合ArrayList是不安全的
在这里插入图片描述

上面两个案例,小伙伴可以先思考,或者先动手去实践。

再下一章中会讲出。

最后:

为了更好的阅读体验,我把想说的话都放在了下面,嘿嘿。

我是一颗剽悍的种子 把我会的,认真的分享 是我写博客一直不变的信条。
如果你能看到这篇博文,说明咱们还是很有缘的;希望能带给你一些许帮助,创作的不易,
把我文章的知识带走,你的三连留下,点赞,评论,关注,是我最大的动力。

你可能感兴趣的:(多线程&并发)