线程与锁在并发编程的作用相当于铆钉和工字梁在土木工程中的作用,一个坚固的桥梁离不开大量的且正确的铆钉和工字梁的使用。因此线程与锁的正确的使用关乎着整个项目的健壮性与可靠性
要编写线程安全的代码其核心在于对状态访问操作的管理,特别是对于共享和可变的状态的访问
对象的状态实际上就是成员变量的数据,共享意味着是否能被多个线程访问,可变意味着在变量的生命周期中能否可以变化
一个对象是否是安全的并不取决于对象的功能,而是在程序中被访问的方式
因此为了保证线程安全往往采用"同步"的方式来去保证。对于java中的同步方式有多种--synchronized关键字,volatile关键字以及原子性类对象。。。
当我们进行设计程序的时候往往首先需要考虑线程安全的问题,原因很简单如果当初设计的时候就无法保证线程安全那么在后续程序调试的时候则会很难找出问题所在地,同时后续将线程不安全的程序改造成线程安全的程序的成本往往也是巨大的
那么究竟什么是线程安全呢,这其实是一个模糊的定义,定义的越正式就越难理解。我的理解是--
如果某个类可以在多线程中安全的使用,那么这个类就是线程安全的。所谓的安全使用则是该类的任何方法不管线程调用的时序都能表现出正确的行为。
在进行同步的时候一般采用了以下几种方式原子性类,synchronized关键字等。但是需要注意的是在一个类中如果是有多个状态变量往往则是采用synchronized的代码块的形式进行同步(并不是只是修改的时候才需要同步,对于一些读取操作也是需要同步的,如果仅仅使用原子性类则无法保证同步)
每一个共享和可变的变量都应该只由一个锁来保护,这样降低了开发人员的维护成本
并且需要注意的是并不能直接将整个方法都加上锁,这样会严重降低性能,要在进行并发操作的代码块上添加锁,在性能与安全之间取一个平衡点
同时我们应遵循先保证安全再提高性能的原则。