Java synchronized用法

synchronized 的语法:

  synchronized 可以作为一个method的修饰符,也可以一段代码里出现,先说在代码里出:

  其语法是

  synchronized(xx) {

  //your code

  }

  这个xx需要是一个Object,只要是一个Object就行,如:

  String s="haha";

  synchronized(s) {

  //your code

  }

  不是Object不行,如:

  int n=3;

  synchronized(n) {

  //your code

  }

  是不可以的,有autoboxing也不行。

  如果你理解this的含义,那么

  synchronized(this) {

  //your code

  }

  也很好理解,它需要一个Object,而this是一个特殊的Object,当然可以这样用。

  再说synchronized 修饰 method的情况,如果synchronized修饰一个非static的method,

  如:

  public synchronized void aMethod() {

  //some code

  }

  相当于:

  public void aMethod() {

  synchronized(this) {

  //some code

  }

  }

  修饰一个 static的method,

  如:

  public static synchronized void aMethod() {

  //some code

  }

  相当于:

  public static synchronized void aMethod() {

  synchronized(XX.class) {

  //some code

  }

  }

  XX是这个方法所在的类,XX.class 也是一个Object,类型是Class而已,在一个

  ClassLoader里,它是唯一的,就是独一无二的object

  总之synchronized的语法可以统一为: synchronized(a var) { do something }

  synchronized 的语义:

  这是我自己的理解,

  synchronized(xx) {

  //your code

  }

  的语义是,在xx这个Object的“授权”、“名义”、 “面子”下,执行 your code。要注

  意的是,xx只能授权给一个人(线程),当xx授权给某个人执行后,就不能再授权给别人了

  。 当那个人执行完那段代码后,xx才能继续授权给其它人执行,可以理解为,别人在xx的

  授权下,执行完这段代码后,把这个权利又还给xx了。 当xx不能授权给一个人时,这个人

  必须等在这里,知道xx可以授权给它。 (上面说的人都是线程)

  synchronized 的作用:

  synchronized是用在多线程环境中的,作用简单的说,就是不允许 “某些” 线程 同时执

  行到一段代码里。 这个 “某些”线程 怎么界定? 是由那个xx object决定的,就是当两

  个线程执行到 synchronized的时候,需要同一个Object授权时,这两个线程不能同时执行

  到需要授权的代码。

  极端情况是 系统你所有的线程都不能执行到这段代码里,那么你就选一个极端唯一的

  object作为xx,一般选Class object,如:

  synchronized(String.class) {

  }

  具体到应用比较复杂,举两个例子:

  1:

  public class Test1 implements Runnable {

  public void run() {

  synchronized(this) {

  try {

  System.out.println(System.currentTimeMillis());

  Thread.sleep(2000);

  System.out.println(System.currentTimeMillis());

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  }

  }

  public static void main(String[] args) {

  Test1 test=new Test1();

  for(int i=0;i<10;i++) {

  new Thread(test).start();

  }

  }

  }

  2:

  public class Test1 implements Runnable {

  public void run() {

  synchronized(this) {

  try {

  System.out.println(System.currentTimeMillis());

  Thread.sleep(2000);

  System.out.println(System.currentTimeMillis());

  } catch (InterruptedException e) {

  e.printStackTrace();

  }

  }

  }

  public static void main(String[] args) {

  for(int i=0;i<10;i++) {

  new Thread(new Test1()).start();

  }

  }

  }

  两个例子中,都有一段synchronized的代码。

  在1中,main方法中创建的10个线程 不能同时进入到那段代码执行,因为这10个线程需要让同一个object授权,而在2中,main方法中创建的10个线程 可以同时进入到那段代码执行,因为10个线程是让不同的object授权的,均授权成功,同时进入到那段代码执行

  补充:

  零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。

  class Foo implements Runnable{

  private byte[] lock = new byte[0]; // 特殊的instance变量

  Public void methodA(){

  synchronized(lock) { //… }

  }

  //…..

  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值