多线程编程:对象及变量的并发访问:
- volatile 关键字
- synchronized 同步方法
- synchronized同步语句块
volatile 关键字:
关键字volatile的主要作用是使变量在多个线程间可见 。
如果不在多继承的情况下, 使用继承Thread类 和实现Runnable接口在取得程序运行的结果上并没有什么太大的区别。如果一旦出现多继承的情况,则实现Runnable接口的方式来处理多线程的问题就是很有必要的。
一般情况下变量的值是从工作内存读取, 不同线程就会从不同工作内存读取, 如果要访问公共堆栈中读取数据,就必须通过使用Volatie关键字,强制从公共内存中读取变量的值,增加了实例变量在多线程之间的可见性。
但volatie关键字最致命的缺点是不支持原子性, 例如 i=i+1;这样的操作并不是一个原子操作,也就是非线程安全的。
AtomicInteger 可以在没有锁的情况下做到线程安全。原子类也并不完全安全, 必要时需要使用synchronized来解决方法之间的调用。
Synchronized
两个线程同时访问一个没有同步的方法,如果两个相乘同时操作业务对象中的实例变量,则有可能出现“非线程安全”问题,加上synchronized即可。
调用关键字synchronized声明的方法一定是排队运行的, 另外需要牢记共享这两个字, 只有共享资源的读写访问才需要同步化, 如果不是共享资源,就没有同步的必要。
同步方法的弊端效率低, 所以使用synchronized同步代码块,一半同步,一半异步。
Synchronized(非this对象x)同步代码块格式进行同步操作时,对象监视器必须是同一对象,如果不是同一对象监视器,运行结果就是异步调用了,
静态同步synchronized方法与synchronized(class)代码块:
关键字也可以用在static静态方法上,如果这样写,那就是对当前的*.java文件对应的Class类进行持锁,而加到非对象方法上是给对象上锁 。
多线程的死锁(deadLock):
死锁是程序设计的Bug, 在设计程序时就要使用避免双方互相持有对方的锁的情况。