黑马程序员技术交流社区

标题: synchronized 方法同步于代码同步块有什么区别 [打印本页]

作者: ⑷嚸V恱    时间: 2013-8-12 09:09
标题: synchronized 方法同步于代码同步块有什么区别
  synchronized 修饰代码同步块时候,方法里面没有其成员 ,这个时候用方法同步与代码同步有什么不同,下面是毕老师的代码片段

下面是毕老师讲的代码片段:
   class Bank {
      private int sum;
      public syschronized void add(int n){
            sum=sum+n;
            try{
                 Thread.sleep(10);
             catch(Exception e){
              }
                 System.out.println("sum="+sum);
          }
      }
  }


  class Bank {
      private int sum;
      Object obj=new Object();
      public void add(int n){
           syschronized (obj)
           {
                     sum=sum+n;
                     try{
                           Thread.sleep(10);
                          }
                            catch(Exception e){}
                 System.out.println("sum="+sum);
              }
        }
  }
作者: 曹奎    时间: 2013-8-12 10:10
【Synchronized同步的原理:】将需要同步的代码进行封装,并在该代码上加上一个锁。
【同步的好处】
       解决了多线程的安全问题;
【同步的弊端】
       会降低性能,损耗性能。
【同步的前提】
必须要保证在同步中有多个线程。因为同步中只有一个线程该同步就毫无意义。必须保证多个线程在同步中使用的是同一个锁。
必须保证多个线程使用的是同一个锁,这是才称为多个线程被同步了!

【同步函数】——同步的另一种表现形式。直接用synchronized 修饰函数即可。

【同步函数用什么锁?】
       函数肯定被对象调用。代表调用函数对象的引用就是this。也就是说:同步函数使用锁是this。

【同步函数 和 同步代码块有什么区别呢?】
1. 同步函数比同步代码块写法简单。
2. 同步函数使用的锁是this.同步代码块使用的锁是任意指定的对象。
建议开发时,使用同步代码块儿。尤其是需要不同锁时。


【静态同步函数使用的锁是什么?】
静态进内存时,对象还没有创建,不能使用对象作为锁。静态随着类的加载而加载,这是内存中存储的对象至少有一个就是该类字节码文件对象。这个对象的表示方式:——类名.class 它就表示字节码文件对象。

【同步的另一个弊端:】——死锁。【两根 筷子,吃饭!】
最常见的死锁情况:同步嵌套(最常见的情景之一)。同步中还有同步,两个同步用的不是一个锁。
作者: ⑷嚸V恱    时间: 2013-8-12 10:24
曹奎 发表于 2013-8-12 10:10
【Synchronized同步的原理:】将需要同步的代码进行封装,并在该代码上加上一个锁。
【同步的好处】
       ...

1. 同步函数比同步代码块写法简单。
2. 同步函数使用的锁是this.同步代码块使用的锁是任意指定的对象。
建议开发时,使用同步代码块儿。尤其是需要不同锁时。

那根据上面的代码 开发的时候会用哪一种形式同步呢?上面的代码这两种形式有什么必然的区别吗?
作者: sergio    时间: 2013-8-12 11:19
本帖最后由 sergio 于 2013-8-12 11:27 编辑

都是去给当前this对象加锁,都可以起到线程安全的效果。区别如下:
1、加到成员方法中,代表整个成员方法都需要同步,
2、加到同步代码中,代表整个synchronized(共享对象){}中的语句需要做同步。
区别:加到同步代码中的控制代码比较精细,方法中的整个代码块都需要。可能在成员方法中的,还有其他代码,有些需要同步有些不需要同步。如果只需要对需要的代码,可以用synchronized关键字包装起来就行,达到线程安全,而不影响其他的剩下的代码。如果要怎么使用,按需要尽量使用对需要代码同步即可,但是同步中的丧失的是效率,效率可能会大打折扣,此策略也可提高一定的效率。

作者: ⑷嚸V恱    时间: 2013-8-12 14:55
sergio 发表于 2013-8-12 11:19
都是去给当前this对象加锁,都可以起到线程安全的效果。区别如下:
1、加到成员方法中,代表整个成员方法都 ...

先说声3q
加到同步代码中的控制代码比较精细,方法中的整个代码块都需要。可能在成员方法中的,还有其他代码,有些需要同步有些不需要同步。如果只需要对需要的代码,可以用synchronized关键字包装起来就行,达到线程安全,而不影响其他的剩下的代码。
上面这个区别额有了解。我想问的就是如果编写代码的时候就出现了上面的这两种情况,成员方法中没有其他的代码,这个时候我是选择 同步块,还是同步函数,还是这个时候两者没有什么本质上的区别,用哪个都可以呢?
作者: sergio    时间: 2013-8-12 15:08
⑷嚸V恱 发表于 2013-8-12 14:55
先说声3q
加到同步代码中的控制代码比较精细,方法中的整个代码块都需要。可能在成员方法中的,还有其他 ...

你都没块怎么同步。  这个时候是同步函数了
作者: ⑷嚸V恱    时间: 2013-8-12 15:38
sergio 发表于 2013-8-12 15:08
你都没块怎么同步。  这个时候是同步函数了

这个不是同步块吗
  1. class Bank {
  2.       private int sum;
  3.       Object obj=new Object();
  4.       public void add(int n){
  5.            syschronized (obj)
  6.            {
  7.                      sum=sum+n;
  8.                      try{
  9.                            Thread.sleep(10);
  10.                           }
  11.                             catch(Exception e){}
  12.                  System.out.println("sum="+sum);
  13.               }
  14.         }
  15.   }
复制代码





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