一、线程安全与不安全
非线程安全其实会在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的结果就是脏读,就是取到的数据其实是被更改过的。而线程安全就是已获得的实例变量的值是经过同步处理的,不会出现脏读现象。非线程安全问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程安全”问题,所得的结果也就是“线程安全”的。
二、synchronized关键字
synchronized关键字得到的锁是对象锁;出现异常时,锁自动释放;synchronized同步不具备继承性。其主要应用于同步方法与同步代码块。另外,关键字synchronized拥有锁重入的功能,也就是使用synchronized时,当一个线程得到一个对象锁,再次请求该对象锁时是可以再次得到该对象锁的。这也证明了在一个synchronized方法/块的内部调用本类的其他synchronized方法/块时,是可以永远得到锁的。
1、在同步方法中的使用(弊端是效率低下)
关于同步方法和非同步方法:
1)A线程先持有object对象的Lock锁,B线程可以以异步的方式调用object对象中的非synchronized方法。
2)A线程先持有object对象的Lock锁,B线程如果在此时调用object对象中的synchronized类型的方法则需等待,也就是同步。
2、在同步代码块的使用
当两个并发线程访问一个对象的object中的synchronized(this)同步代码块时,一段时间内只能有一个线程被执行,另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码。不在synchronized块中就是异步执行,在synchronized块中就是同步执行,即一半同步,一半异步。
在多个线程持有“对象监视器”为同一个对象的前提下,同一个时间只有一个线程可以执行synchronized(非this对象x)同步代码块中的代码;当持有“对象监视器”为同一个对象的前提下,同一个时间只有一个线程可以执行synchronized(非this对象x)同步代码块中的代码。synchronized(非this对象x)格式的写法是将x对象本身作为“对象监视器”。可以得出3个结论:
1)当多个线程同时执行synchronized(x){}同步代码块时呈现同步效果。
2)当其他线程执行x对象中synchronized同步方法时呈同步效果。
3)当其他线程执行x对象方法里面的synchronized(this)代码块时也呈现同步效果。
但须注意:如果其他线程调用不加synchronized关键字的方法时,还是异步调用。
补充说明:
1、synchronized关键字加到static静态方法上是给Class类上锁,而synchronized关键字加到非static静态方法上是给对象上锁。
2、synchronized关键字中的对象锁的理解:当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对同一个object中所有其他synchronized(this)同步代码块的访问将被阻塞,这说明synchronized使用的“对象监视器”是一个。