黑马程序员技术交流社区

标题: 多线程当中synchronized关键字的问题 [打印本页]

作者: 吴扬    时间: 2012-6-13 10:41
标题: 多线程当中synchronized关键字的问题
本帖最后由 吴扬 于 2012-6-21 02:11 编辑

大家都知道,在多线程当中为了不是程序出现死锁的情况,可以用synchronized关键字将需要访问同一资源的代码进行同步。synchronized关键字既可以加在对象上,也可以加在方法上,这两种用法有什么区别吗?各自有没有什么优缺点呢?

作者: 黄捷    时间: 2012-6-13 11:08
当synchronized用在方法上时,称该方法为同步方法,如:
public synchronized void method()
{   
}  
这时,synchronized锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法

synchronized加在方法上本质上还是等价于加在对象上的。
如果synchronized加在一个类的普通方法上,那么相当于synchronized(this)。
如果synchronized加载一个类的静态方法上,那么相当于synchronized(Class对象)。

你说的锁在对象上应该说的同步代码块,同样举例如下:
public void method(Object  obj) {   
synchronized(obj)   
{   
}   
}   
当有一个明确的对象作为锁时,就能够这样写程式,但当没有明确的对象作为锁,只是想让一段代码同步时,能够创建一个特别的Object变量(他得是个对象)来充当锁。




作者: 王月    时间: 2012-6-13 11:13
这两种形式都是为了程序的安全。

1,synchronized加在方法上
例如:
public synchronized void run();

每个 synchronized 方法都必须获得调用run方法的锁方能执行,否则线程阻塞,方法一旦执行,其他线程就不允许在进入,直到从该方法返回时才将锁释放。
优点:这种机制确保了同一时刻, synchronized 的成员函数中只能有只有一个处于可执行状态,从而有效避免了类成员变量的访问冲突。
缺点:如果方法中执行的内容很多,就会影响到效率。因为在线程的整个生命期内它一直在运行,所以它对本类任何 synchronized 方法的都不能调用。

2,synchronize块
例如:
synchronized(Object) {
//代码
}
1,因为synchronize加在方法上会可能会导致效率问题,所以出现了代码块。(要声明是哪个对象的锁)
优点:它可以针对任意代码块,而且可任意指定锁的对象,所以灵活性较高。
缺点:如果方法中代码很多时,用代码块显得会很臃肿,程序没有阅读性

作者: 黄克帅    时间: 2012-6-13 11:22
在多线程当中为了不是程序出现死锁的情况,可以用synchronized关键字将需要访问同一资源的代码进行同步。这几句话错了
死锁的情况,根本就是使用同步造成的,通常是同步中嵌套同步,而各自使用的锁不同造成死锁。 没有同步  没有锁,何来死锁。
同步的弊端就是每次要判断锁,比较消耗资源。 所以在程序中通常只在在需要同步的代码上加锁。  锁作用的范围越大,程序执行的效率越低。直接加在类上,就是整个类同时只能有一个线程访问,其中与同步无关的代码也同步了,效率会很低。  
作者: 吴扬    时间: 2012-6-21 02:10
王月 发表于 2012-6-13 11:13
这两种形式都是为了程序的安全。

1,synchronized加在方法上

谢谢哥们儿,已经讲得很清楚了!
作者: 王月    时间: 2012-6-21 09:44
吴扬 发表于 2012-6-21 02:10
谢谢哥们儿,已经讲得很清楚了!

小事小事
作者: 徐传任    时间: 2012-10-10 12:19
看看...........................




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2