黑马程序员技术交流社区

标题: 多线程同步代码块和同步方法中,锁对象的原理是怎么样的? [打印本页]

作者: 付鑫鑫    时间: 2013-4-22 20:55
标题: 多线程同步代码块和同步方法中,锁对象的原理是怎么样的?
本帖最后由 付鑫鑫 于 2013-5-13 17:38 编辑

为什么同步代码块的锁对象可以,用任意锁对象.而同步代码块同步方法只能this为锁对象.
作者: 曹睿翔    时间: 2013-4-22 23:53
稍后云版块会推出学习过程中问题以及对知识点的领悟收集!会有技术分奖励,敬请期待、多多参与,要注意按照进度收集问题,那样你会事半功倍。

作者: 王溢君    时间: 2013-4-23 00:43
因为函数前面省略了this.
作者: Neverbelazy    时间: 2013-4-23 02:22
本帖最后由 Neverbelazy 于 2013-4-23 02:29 编辑

我理解你的问题可以分成下面几个部分解答:
1. Java工程师在设计同步的时候,需要让所可以是任意对象的。
2. 同步方法是一种同步的简写形式,简写就可能付出局限性的代价,
比如下面,这两个是等价的,不过同步方法看起来更简便,但好处似乎又不止这一点,因为一旦定义了synchronized方法,就相当于让外界知到了这个方法是同步的,满足了封装性,又对外提供了方法属性描述
  1. public synchronized void method(){};
  2. //-----------vs-----------------
  3. public void method(){
  4. synchronized(this){
  5. }
  6. }
复制代码
3. 那么,剩下的问题是 为什么不可以这样定义 同步方法; (这一点我也不知道原因, 不知道是java工程师们有更多的考虑,还是根本没有必要这样定义, 这点还需要请高手解答)
  1. public synchronized(object) void method(){}
复制代码
4. 最后的问题是,怎么验证同步方法的 锁是 this,毕老师的视频里面给出过一个方法,不过比较复杂,不容易放在帖子上说明,下面提供一段小代码,可以验证同步方法的锁是this
  1. /*
  2. * 1. 造一个带同步函数的线程t1
  3. * 2. 在主函数中加一个同步代码块,同步代码块的锁设定为“调用同步函数”的那个对象(相当于this)
  4. *    现在系统中两个线程:main 和 t1
  5. * 3. 线程内的同步代码为无限循环输出当前线程的名称
  6. * 4. 如果每次输出只是一个线程的名字,即证明两段同步代码公用一把锁,就是说同步方法的锁=2.中传给同步代码块的锁(“调用同步函数”的那个对象)
  7. */
  8. public class SynchronizedMethodTest {
  9.         public static void main(String[] args){
  10.                 MyThread mt=new MyThread();        //mt对象继承Runnable,课调用run方法传给线程
  11.                 Thread t1=new Thread(mt);        //t1线程传入mt对象
  12.                 t1.start();                                 //t1开始,调用run() run调用 synchronized printed (mt=this)
  13.                 synchronized(mt){                        //定义同步代码块:传入mt,此时主线程和t1线程用的同步部分用同一把锁
  14.                         while(true)
  15.                         System.out.println(Thread.currentThread());
  16.                 }
  17.                
  18.         }
  19. }
  20. //定义一个类继承Runnable
  21. class MyThread implements Runnable{
  22.         public void run(){
  23.                 print();
  24.         }
  25.         public synchronized void print(){         //定义同步方法 要与同步代码块比较
  26.                 while(true)
  27.                 System.out.println(Thread.currentThread());
  28.         }
  29. }
复制代码
5.补充:静态同步函数的锁是  “类型.class” 对象




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