并发(concurrency)一个并不陌生的词,简单来说,就是cpu在同一时刻执行多个任务。
而Java并发则由多线程实现的。
在jvm的世界里,线程就像不相干的平行空间,串行在虚拟机中。(当然这是比较笼统的说法,线程之间是可以交互的,他们也不一定是串行。)
多线程的存在就是压榨cpu,提高程序性能,还能减少一定的设计复杂度(用现实的时间思维设计程序)。
这么说来似乎线程就是传说中的银弹了,可事实告诉我们真正的银弹并不存在
死锁和脏数据就是典型的线程安全问题。
简单来说,线程安全就是: 在多线程环境中,能永远保证程序的正确性
只有存在共享数据时才需要考虑线程安全问题
其中, 方法区和堆就是主要的线程共享区域。那么就是说共享对象只可能是类的属性域或静态域
那么,什么才是线程安全的呢?
如果你在Google搜索就会出现许多像这样的“定义”:
- 线程安全的代码是多个线程同时执行也能工作的代码
- 如果一段代码可以保证多个线程访问的时候正确操作共享数据,那么它是线程安全的
你有没有觉得上面的定义似乎没有传达任何有意义的信息,反而会让你更混乱。 虽然这些定义都是没错的,但事实是没有提供任何实际的帮助和观点,
我们如何区分线程安全类和不安全类呢?线程 “安全” 是什么意思?
线程安全任何合理定义的核心都是在讲线程安全的正确性。因此,在了解线程安全之前,我们首先应该了解这个 “正确性”
正确性意味着类的行为符合规范
你当然认可这个定义,一个好的类规范会在任何时间都可以获得类的状态信息,并且可以对它进行操作。 通常我们没有一个准则来定义自己的类是否符合规范,怎么知道它们是正确的? 当然不知道,但我们依然可以使用它,一旦我们能够让自己的 “代码有效”。 这种 “代码自信” 与我们接近正确性有关
只要把“正确性”定义为我们可以理解的内容,现在我们可以用一种非专业的解释来定义它:当一个类被多个线程进行访问并且正确运行,它就是线程安全的。
当多个线程访问某各类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或者协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。