您的位置:首页 > 编程语言 > Java开发

java中的synchronized关键字

2017-05-22 18:54 302 查看
【1】synchronized方法:

说明:如果A线程调用了某个实例对象的某个synchronized方法M,则A线程就获得了这个实例对象的锁,在A线程调用M方法结束之前(即A线程释放该实例对象的锁之前),其它线程不能调用该实例对象的任何synchronized方法和任何synchronized(this)同步代码块,因为其它线程无法获取到该实例对象的锁。

1)哪个线程先执行带synchronized关键字的方法,哪个线程就持有该方法所属对象的锁。
2)synchronized方法获取的锁是对象锁,故线程锁的是对象。
3)synchronized锁重入
1>当A线程得到一个对象锁后,再次请求该对象锁时,是可以再次得到该对象的锁。
2>在一个synchronized方法/块的内部调用本类的其它synchronized方法/块时,是永远可以得到锁的。
3>当一个线程得到一个对象锁后,这个线程也可以调用该对象从父类继承过来的synchronized方法。
注意:synchronized关键字不具有继承性:
eg:
父类中的方法:synchronized public void method() { ... }
子类中的方法:public void method() { ... }

此时,调用子类中的method方法时,该方法并不是同步的。
如果想让子类中的method方法是同步的,则应该将继承过来的method方法声明为synchronized 即:synchronized public void method() { ... }

4)出现异常,锁自动释放:当一个线程执行的代码出现异常时,该线程持有的锁会自动释放。

【2】synchronized语句块:
1)this对象作为锁的同步代码块:即synchronized(this)
说明:当一个线程访问一个对象的某个synchronized(this)同步代码块时,其它线程对该对象的synchronized方法和synchronized(this)同步代码块的访问将被阻塞。
2)非this对象作为锁的同步代码块:即synchronized(非this对象)
1>优点:一个对象中的synchronized(非this对象)同步代码块不会与该对象中的synchronized方法争抢this锁,二者间的调用时异步的。
2>说明:当一个线程访问一个对象的某个synchronized(非this对象)同步代码块时,其它线程可以访问该对象的synchronized方法,因为二者锁定的对象不同。
3>注意:当一个线程访问一个对象O的某个synchronized(非this对象X)同步代码块时,其它线程不可以访问X对象中的synchronized方法和synchronized(this)同步代码块,但是可以访问O对象中的synchronized方法或synchronized(this)代码块。

【3】静态synchronized方法 与 静态synchronized(class)代码块
1)持有的锁是类的Class锁。
2)调用前必须先获取到所属的类的Class锁。
3)静态synchronized方法和非静态synchronized方法持有的是不同的锁:静态synchronized方法持有的是Class锁,非静态synchronized方法持有的是对象锁,静态同步代码块与非静态同步代码块也是如此。
4)Class锁可以对类的所有对象实例起作用,换句话说:如果一个线程通过该类的某个对象实例已经获取到了该类的Class锁,则其它线程无法通过另外的对象实例来获取到该类的Class锁。

【注意】

1)锁对象的改变
private String lock = "abc";
synchronized (lock) {	// 此时(即第一次调用时)锁对象是"abc"
lock = "asdf";		// 这行执行完成后,其它线程调用该代码块时,锁的对象就变成"asdf"了
}

2)锁对象属性的改变不会引起锁的改变
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: