锁,是用来在多线程做同步操作,是线程同步的一种实现方式,锁住需要同步代码,只能让单个线程访问。
锁住的是一个对象,对于这被锁住的对象,加了锁的会同步访问,没有加锁的就随机访问。
锁代码块,方法,对象,类。要区分他们的作用范围。
block<=Method<Object<Class
- 锁Block的时候,锁方法所有的代码就相当于锁方法
- 锁Object的时候,他的所有的方法都同步执行。
- 锁Class的时候,他的所有类对象执行到这个锁的地方是,都同步。
锁代码块
一个线程访问锁住的代码块时,一定是按次序来。
在方法中对于余下没有锁住的是随机的。这个随机要看线程获取CPU的能力强弱,先获取就先执行。至于执行多少,要看在每个CPU执行片段期间到底执行了多少。
1 | public void run() { |
JSBySynchronizedBlock
被锁的代码块是同步访问,其他的就随机
锁方法
在方法前面加synchronized,public synchronized void method(){//todo}
。作用范围是整个方法,而锁代码块的作用方法是synchronized{}
花括号的内容。
所以以下两者是等效的
1 | public synchronized void method() |
synchronized关键字不能继承
synchronized并不属于方法定义的一部分,因此,synchronized关键字不能被继承。
如果在父类中的某个方法使用了synchronized关键字,而在子类中覆盖了这个方法,必须显式地在子类的这个方法中加上synchronized关键字才可以同步。
还可以在子类方法中调用父类中的方法super,单余下的其他的代码还是非同步的。
在子类方法中加上synchronized关键字
1 | class Parent { |
在子类方法中调用父类的同步方法
1 | class Parent { |
- 在定义接口方法时不能使用synchronized关键字。
- 构造方法不能使用synchronized关键字,但可以使用synchronized代码块来进行同步。
锁静态方法
1 | public synchronized static void method() { |
静态方法是属于类的而不属于对象的。同样的,synchronized修饰的静态方法锁定的是这个类的所有对象。
锁对象
1 | public void method3(SomeObject obj) |
对于这个被锁住的对象,调用该对象的所有的方法都会同步。然后,对于多个同时锁改对象的代码块内部也是同步的(不是该对象的其他的方法)也是同步的。
锁类
不是在类申明的时候加锁而是
1 | class ClassName { |
JSBySynchronizedClass
效果跟锁类的静态方法一样,对于类的所有对象,调用锁类方法都会同步。