黑马程序员技术交流社区

标题: java中多线程同步synchronized [打印本页]

作者: sbeeqnui1987    时间: 2012-6-14 21:05
标题: java中多线程同步synchronized
synchronized
在线程同步的时候为什么要使用对象监视器,什么是对象监视器?

有同步块和同步方法,同步块前加synchronized(对象){  },为什么要有括号中的对象?这个对象的作用是什么?如果没有对象这个对象监视器会怎么样?


这个对象应该是哪个对象,可能我说的不够准确,或者应该说这个对象的监视器应该是哪个对象的监视器,是随便的吗,还是有什么要求?也不能太随便吧。

例如在一个方法里,有synchronized块,这个对象监视器应该是?
作者: 刘克方    时间: 2012-6-14 21:09
本帖最后由 刘克方 于 2012-6-14 21:24 编辑

synchronized在线程同步的时候为什么要使用对象监视器,什么是对象监视器?

具体解释:因为通过对象监控器才可以知道当前代码块是否有其他线程在执行,所以要使用对象监控器;
每个对象都有0和1标志位,通过它标志位的改变来控制同步锁的打开和关闭;

有同步块和同步方法,同步块前加synchronized(对象){  },为什么要有括号中的对象?这个对象的作用是什么?如果没有对象这个对象监视器会怎么样?
具体解释:括号中的对象为锁,如果已经有线程正在执行其中的代码,其标志位为1,代码块别锁定,其他线程无法进入;
当执行后标志位为0,表示其他线程进入可以执行其中代码

这个对象应该是哪个对象,可能我说的不够准确,或者应该说这个对象的监视器应该是哪个对象的监视器,是随便的吗,还是有什么要求?也不能太随便吧。

具体解释:这个对象没有具体要就,每个对象都可以当做锁;


作者: 郑冬    时间: 2012-6-14 21:26
对象监视器用来 监视多个线程处理同一个共享数据,比如成员变量,

对于你说的那个大括号里面的对象 这个对象你可以自己定义,比如 String  str=new Stirng("11");

Object  obj=new Object();这都可以  这个对象 主要用来 标示的 就好比是一个锁,如果你两个线程都要访问一个共享数据的话,当然 这个对象要是一样的,synchronized(对象){  }这里的对象 必须的有,这是规范



作者: 梁清平    时间: 2012-6-14 22:34
本帖最后由 梁清平 于 2012-6-14 22:36 编辑

synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块。
       首先,同步代码块中的监视器对象可以是任何一个对象。哪怕是Object也没问题。同步方法中用的锁是
this,也就是调用该方法的当前对象,如果方法是静态的,那么用的锁是这个类的class文件对象。不管
的是哪个锁前提是需要同步的代码需要用同一把锁,否则同步无效!
  1. synchronized 方法:通过在方法声明中加入 synchronized关键字来声明 synchronized 方法。如:
public synchronized void accessVal(int newVal);
synchronized 方法控制对类成员变量的访问:每个类实例对应一把锁,每个 synchronized 方法都必须
获得调用该方法的类实例的锁方能执行,否则所属线程阻塞,方法一旦执行,就独占该锁,直到从该方法
返回时才将锁释放,此后被阻塞的线程方能获得该锁,重新进入可执行状态。这种机制确保了同一时刻对
于每一个类实例,其所有声明为 synchronized 的成员函数中至多只有一个处于可执行状态(因为至多只
有一个能够获得该类实例对应的锁),从而有效避免了类成员变量的访问冲突(只要所有可能访问类成员
变量的方法均被声明为 synchronized)。
在 Java 中,不光是类实例,每一个类也对应一把锁,这样我们也可将类的静态成员函数声明为
synchronized ,以控制其对类的静态成员变量的访问。
synchronized 方法的缺陷:若将一个大的方法声明为synchronized 将会大大影响效率,典型地,若将线
程类的方法 run() 声明为 synchronized ,由于在线程的整个生命期内它一直在运行,因此将导致它对
本类任何 synchronized 方法的调用都永远不会成功。当然我们可以通过将访问类成员变量的代码放到专
门的方法中,将其声明为 synchronized ,并在主方法中调用来解决这一问题,但是 Java 为我们提供了
更好的解决办法,那就是 synchronized 块。
2. synchronized 块:通过 synchronized关键字来声明synchronized 块。语法如下:
synchronized(syncObject) {
//允许访问控制的代码
}
synchronized 块是这样一个代码块,其中的代码必须获得对象 syncObject (如前所述,可以是类实例
或类)的锁方能执行,具体机制同前所述。由于可以针对任意代码块,且可任意指定上锁的对象,故灵活
性较高。

作者: 胡卿    时间: 2012-6-14 23:06
  同步函数使用的锁是this。
           同步代码块使用的锁可以是任意对象。

     特殊:静态同步函数使用的锁是 该函数所属类对象字节码文件对象。 类名.class


作者: 李海    时间: 2012-6-14 23:30
   同步中所传入的对象是任意的     目地就是为了让你分清楚多线程使用的是哪一个锁   这样有利于处理多线程的安全问题   
   补充一点知识:  非静态的同步函数的对象是this   静态同步函数的对象是本类类名.class    对于同步代码块而言   只要是对象就可以  但是必须在函数中声明哦  
   求加分啊~~~




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