前言
可能有人会觉得,只要我写代码的时候不去开启其他线程,那么就不会有多线程的问题了。
然而事实并非如此,如果仅仅是一些简单的测试代码,确实代码都会顺序执行而不是并发执行,但是Java应用最广泛的web项目中,绝大部分(如果不是所有的话)web容器都是多线程的——以tomcat为例, 每一个进来的请求都需要一个线程,直到该请求结束。 这样一来,即使本身不打算多线程运行的代码,实际上几乎都会以多线程的方式执行。
在 Spring 注册的 bean(默认都是单例),在设为单例的 bean 中出现的成员变量或静态变量,都必须注意是否存在多线程竞争导致的多线程不安全的问题。
——可见,有些时候确实都是人在江湖,身不由己。积累多线程的知识是必不可少的。
1.为什么会有多线程不安全的问题
1.1.写不安全
上面讲到 web 容器会多线程访问 JVM,这里还有一个问题,为什么多线程时就会存在多线程不安全呢?这是因为在 JVM 中的内存管理,并不是所有内存都是线程私有的,Heap(Java堆)中的内存是线程共享的。
而 Heap 中主要是存放对象的,这样多个线程访问同一个对象时,就会使用到同一块内存了,在这块内存中存着的成员变量就会受到多个线程的操作。
如下图所示:
因为是增加2和3