一、含义
Synchronized作为java的关键字,可以在后面带上修饰的对象,加上代码块,也可以修饰方法。
它的含义可以理解为:执行代码块的语句之前,必须获得修饰的对象的锁。
具体可以分为以下几种情况:
1.修饰对象是一个类对象,作用范围是整个代码块,锁作用于这个类的所有对象,所有的对象共用一个锁;
2.修饰对象是一个具体对象实例,作用范围是整个代码块,执行代码块必须先获得实例的锁;
3.修饰对象是一个方法,作用范围是整个方法,必须获得调用该方法的对象的锁才可以执行;
4.修饰是一个静态方法,作用返回是整个方法,锁作用于这个类的所有对象,所有的对象共用一个锁;
二、作用
多线程编程中,如果没有引入锁的机制,那数据就会存在脏读,数据会错乱。以一个自增的例子来说:
(1)如果没有使用同步锁,1000个线程并发执行对count的自增操作:

执行结果为:
普通递增结果:992耗时:68
得到的结果不是我们要的1000
(2)引入同步锁来修饰自增的方法:


得到的结果:
通过同步锁递增结果:1000耗时:1305
可以发现引入锁之后,我们得到了预期的结果,但同时因为锁竞争的关系,耗时也翻了很多倍。
(3)根据前面的介绍,我们也可以将锁设置在对象中


得到的结果:
通过synchronized修饰对象递增结果:1000耗时:1297
三、拓展
从上面的测试情况中,发现synchronized关键字虽然可以解决并发读写的问题,但是同时也因此导致线程间锁竞争,锁等待的问题,因此性能也急剧下降;
但java也给我们提供了Atomic类,JDK1.5开始提供了java.util.concurrent.atomic包,方便我们无需使用锁就可以进行原子级的操作。


得到的结果:
使用Atomic结果:1000耗时:39
网友评论