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

Java synchronized关键字用法

2017-01-18 10:14 197 查看
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

它修饰的对象有以下几种: 
1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象(这里是指同一对象); 
2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象; 
3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象; 
4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。

给指定的对象加锁:

我们用synchronized 给某一对象加了锁。这时,当一个线程访问这个对象时,其他试图访问这个对象的线程将会阻塞,直到该线程访问这个对象结束。也就是说谁拿到那个锁谁就可以运行它所控制的那段代码。 

当有一个明确的对象作为锁时,就可以用类似下面这样的方式写程序。

public void method3(SomeObject obj)
{
//obj 锁定的对象
synchronized(obj)
{
// todo
}
}
当没有明确的对象作为锁,只是想让一段代码同步时,可以创建一个特殊的对象来充当锁:

class Test implements Runnable
{
private byte[] lock = new byte[0];  // 特殊的instance变量
public void method()
{
synchronized(lock) {
// todo 同步代码块
}
}

public void run() {

}
}
说明:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。

Synchronized修饰方法和方法内的代码块作用是等价的,都是锁住了整个方法的内容。

synchronized修饰静态方法锁住的是这个类的所有对象,因为静态方法是属于类的而不是属于某一个对象的。

synchronized修饰一个类,例如synchronized(T.class),是给这个类T加锁,T的所有对象用的是同一把锁。

小结:

A.
无论synchronized关键字加在方法上还是对象上,如果它作用的对象是非静态的,则它取得的锁是对象;

如果synchronized作用的对象是一个静态方法或一个类,则它取得的锁是对类,该类所有的对象同一把锁。 
B. 每个对象只有一个锁(lock)与之相关联,谁拿到这个锁谁就可以运行它所控制的那段代码。 
C. 实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: