syschronized用法和理解
一、锁不同位置分类
synchronized是Java中的关键字,是一种同步锁。方法锁和对象锁说的是一个东西,即只有方法锁或对象锁 和类锁两种锁(锁加在方法上和类上作用是一样的,没有区别)
它修饰的对象有以下几种:
1.1 修饰一个代码块
被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
1.2 修饰一个方法
被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
1.3 修饰一个静态的方法
其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
1.4. 修饰一个类
其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。
二、理解
2.1 锁普通方法
所谓的锁对象,不锁定类其他的实例(引用的地址在内存中不同),如果有一个类 Math中的方法 非静态add()方法加了 synchronized关键字,两个线程同时对Math的实例对像 math1 的add方法访问,那么先进入add()方法的线程讲拿到对象锁,后进入的将会阻塞,直到锁被释放,但如果存在Math类存在两个实例对象 math1 ,math2 ,两个线程分别获取到不同的对象,锁的对象也不相同,这样就不会相互干扰,相互排斥,那么就不会发生阻塞的现象 ,可以同时执行。
执行结果:
2.2 锁静态方法
但如果add()方法是static ,那么就是锁Math类的所有实例对象了,如果线程1进入math1的add()方法,那么线程2进入math2 的add()一样会被阻塞
执行结果:
2.3多个线程synchronized和非synchronized代码块
当一个线程访问对象的一个synchronized(this)同步代码块时,拿到了这个object的对象锁,其他线程仍然可以访问该对象中的非synchronized(this)同步代码块。但是访问其他的synchronized(this)同步代码块将会被阻塞(锁对象,不仅仅是锁代码块)
执行结果:
2.4 synchronized锁对象和锁类
当syschronized锁对象的时候,不会发生阻塞
执行结果:
2.5 锁类
当syschronized锁类的时候,发生阻塞,必须一个线程释放同步锁,另外线程才能开始重新争夺同步锁
执行结果:
三、性能比较
syschronized不同的写法,会对程序的响应快慢和对CPU利用程度不一样;性能和执行效率的优劣程度从差到优排列:同步方法<同步方法内部代码块<锁一个其他较小的对象
3.1 同步方法体
3.2 同步方法内部代码块
同步方法体内的代码块相比于同步方法体,优势在于阻塞的线程是分配好这个方法体资源后,才被阻塞等待(,进入方法体是需要时间分配资源)。如果被阻塞在方法体外,那当这个线程拿到对象锁的时候,才分配资源
3.3 锁一个其他较小的对象
相比于3.2中的syschronized(this),锁的对象就是Math这个类实例对象,加锁和释放锁都需要这个对象的资源,如果锁的对象越小就会越好,造byte 数组,就再实际里用的很多了