黑马程序员技术交流社区

标题: 关于synchronized的锁对象的问题 [打印本页]

作者: 曾_强    时间: 2012-6-21 17:06
标题: 关于synchronized的锁对象的问题
本帖最后由 jiyixuan 于 2012-6-23 02:29 编辑

多线程中synchronized中需要定义一个锁对象,并传入。但是这个锁对象为任意的都行,但保证唯一。

有点搞不清楚,
1、定义锁对象的原因?只用synchronized关键字就是作为区分不行吗?为什么非得传入一个锁对象?

2、关于锁对象的任意性?Object类可以作为对象传入,程序中的其他类型对象也可以传入。有什么区别吗?
若是没有区别,任意性原则岂不是没有什么用处,怎么能随便用一个对象来用,还不如不用!


嗯。谢过。
作者: 常佳杰    时间: 2012-6-21 17:32
1、定义锁对象的原因?只用synchronized关键字就是作为区分不行吗?为什么非得传入一个锁对象?
定义锁就是要让多个线程同步,只用synchronized关键字的话,你就得把synchronized关键字
加到方法上或类上:
如:
synchronized aMethod(){}
synchronized static aStaticMethod{}
还有一种是对区块进行实行互斥访问
那就得传入一个所对象...

2、关于锁对象的任意性?Object类可以作为对象传入,程序中的其他类型对象也可以传入。有什么区别吗?
若是没有区别,任意性原则岂不是没有什么用处,怎么能随便用一个对象来用,还不如不用!
锁可以是任意对象呀,
你的问题不太明白,自问自答吗?
任意性是关于传进来的对象而说的....



1、synchronized关键字的作用域有二种:
1)是某个对象实例内,synchronized aMethod(){}可以防止多个线程同时访问这个对象的synchronized方法(如果一个对象有多个synchronized方法,只要一个线程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不同的对象实例的 synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法;
2)是某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它可以对类的所有对象实例起作用。

2、除了方法前用synchronized关键字,synchronized关键字还可以用于方法中的某个区块中,表示只对这个区块的资源实行互斥访问。用法是: synchronized(this){/*区块*/},它的作用域是当前对象;
作者: 李海晓    时间: 2012-6-21 17:43
1、只用synchronized关键字就是作为区分不行吗:
如果一个线程,有一个生成1234等等的数的方法,一个取走1234...的数方法,这个两个方法分别被2个线程调用,总共四个线程。
每个方法只允许同一时刻有一个线程调用。
如果只用synchronized关键字,那么如果一个线程调用了取数字的方法,那么,另一个线程生成数字也要等,不就更消耗时间了吗,没有必要。
2.传入某一个参数,比如说this,那就是同一时刻,只能有一个能执行该方法,如果还有一个同步代码块synchronized(this),那么他也不能被其他方法调用,
如果这两个方法,所操作的对象没关联,那么传入另一个参数。比如这个类中的某一个对象等,具体看环境。
作者: sbeeqnui1987    时间: 2012-6-21 18:32
     synchronized关键字可以作为函数的修饰符,也可作为函数内的语句,也就是平时说的同步方法和同步语句块。如果再细的分类,synchronized可作用于instance变量、object reference(对象引用)、static函数和class literals(类名称字面常量)身上。

在进一步阐述之前,需要明确几点:

A.无论synchronized关键字加在方法上还是对象上,它取得的锁都是对象,而不是把一段代码或函数当作锁――而且同步方法很可能还会被其他线程的对象访问。

B.每个对象只有一个锁(lock)与之相关联。

C.实现同步是要很大的系统开销作为代价的,甚至可能造成死锁,所以尽量避免无谓的同步控制。

搞清楚synchronized锁定的是哪个对象,就能帮助我们设计更安全的多线程程序。
     如果instance变量是一个对象,如数组或ArrayList什么的,那上述方法仍然不安全,因为当外界对象通过get方法拿到这个instance对象的引用后,又将其指向另一个对象,那么这个private变量也就变了,岂不是很危险。 这个时候就需要将get方法也加上synchronized同步,并且,只返回这个private对象的clone()――这样,调用端得到的就是对象副本的引用了。
作者: 孙浩迪    时间: 2012-6-21 19:12
    一、当两个并发线程访问同一个对象object中的这个synchronized(obj)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。

     二、然而,当一个线程访问object的一个synchronized(obj)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(obj)同步代码块。

     三、尤其关键的是,当一个线程访问object的一个synchronized(obj)同步代码块时,其他线程对object中所有其它synchronized(obj)同步代码块的访问将被阻塞。

     四、第三个例子同样适用其它同步代码块。也就是说,当一个线程访问object的一个synchronized(obj)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。






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