线程安全性的定义:
当多个线程访问某个类时,不管运行时环境采用何种调度方式或者这些线程将如何交替执行,并且在主调代码中不需要任何额外的同步或协同,这个类都能表现出正确的行为,那么就称这个类是线程安全的。
主要诱因:
存在可变的共享数据,并且同时有多条线程共同操作这些资源
实现线程安全:
线程封闭:线程封闭的对象只能由一个线程拥有,对象被封闭在该线程中,并且只能由这个线程修改。
只读共享:在没有额外同步的情况下共享的只读对象可以由多个线程并发访问,但任何线程都不能修改它。共享的只读对象包括不可变对象和事实不可变对象。
线程安全共享:线程安全的对象在其内部实现同步,因此多个线程可以通过对象的公有接口来进行访问而不需要进一步的同步。
保护对象:被保护的对象只能通过持有特定的锁来访问。保护对象包括封装在其他线程安全对象中的对象,以及已发布的并且由某个特定锁保护的对象。
三大特征:
①原子性
指定代码块是原子操作,线程的多个操作是一个整体,不能被分割,要么就不执行,要么就全部执行完,中间不能被打断。
②可见性
修改共享变量时,立即同步到主存中,并使该修改对其他线程可见
③有序性
为了提高执行效率,java中的编译器和处理器可以对指令进行重新排序,重新排序会影响多线程并发的正确性,有序性就是要保证不进行重新排序(保证线程操作的执行顺序)。
注:需要都满足才能够确保线程安全,比如volatile就只实现了可见性和有序性,而没有实现原子性,因此并不能够保证线程安全