上期我们提到了的案例中,三个窗口线程卖票出现了有窗口卖的票是一样的问题,也就是的“线程不安全问题”,这篇文章我们就来聊聊“线程为什么会出现不安全”。
线程安全最早是由Brian Goetz 在其编写的“Java Concurrency In Practice”(Java并发编程实战)中定义的,它是这样来定义的:
当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,并且不需要额外的同步,或者在调用方代码不做其他的协调操作,这个对象的行为获取的结果仍然是正确的,那个称这个对象是线程安全的。
在我们之前的三个线程卖票的案例,多个线程访问同一个对象的ticket 数据,但是我们发现操作这个对象获取的数据有的时候出现了重复性的错误结果,所以说我们之前写的卖票案例是“线程不安全”的。
虽然知道了三个线程访问ticket 出现重复数据的现象是线程不安全的,但是不知道为什么多线程并发访问数据不安全,所以接下来我们讲围绕“为什么线程并发访问不安全”来讲解。
Java中按照状态可以把对象分为有状态和无状态两种;
无状态对象(Stateless Bean):无状态对象就是没有实例变量的对象,所以也无法保存数据,它不包含域也没有引用其他类的域。又因为无状态对象没有存储的数据那么这个对象也没有什么改变之说所以是不可变的,同样的多线程下对该对象的任意操作都不会改变对象的状态。所以“无状态的对象一定是线程安全的”。定义无状态案例如下: