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授权的,均授权成功,同时进入到那段代码执行 |
|