同步代码块与同步方法、静态同步方法核心要点
总结 :
1 被锁住后不能被访问的是大括号里的代码,而不是synchronized()括号里的对象,对象只是一个标识,通过判定是否是同一个对象来决定是否让其它线程访问大括号里的代码而已,而不是说不能访问这个对象
2 如果在不同地方使用了同一个锁对象,那么在代码块里访问相同的内容时, 先获得锁对象的线程先访问,访问完之后才能让其它线程访问。谁先获得锁对象由代码执行顺序决定
3 非静态同步方法与静态同步方法:
一个对象的非静态同步方法被访问时,该对象其它的非静态同步方法不能同时被其它线程访问,因为非静态同步方法的锁对象就是对象本身this,根据第二条,具有相同锁对象的需要按顺序执行
。。。。。静态同步方法。。。。。。。。。。。。非静态同步方法能够。。。。。。。。。反之亦然~ 因为它们的锁对象不同,一个是类字节,一个是对象
同理,静态同步方法与静态同步方法不能同时被不同线程访问
注意:如果同步代码块与同步方法具有相同的锁对象时,也按上述法则先后访问
synchronized (this) {...}
private synchronized void xxx() {...}
4 一个线程对某对象内同步方法的访问不影响其它线程对该对象非同步方法的访问
下面的代码是我用来测试验证的,可以拿去玩一下~
public class Demo1 { class Inner { private void m4t1() { synchronized (this) { int i = 5; while (i-- > 0) { System.out.println(Thread.currentThread().getName() + " : Inner.m4t1()=" + i); try { Thread.sleep(500); } catch (InterruptedException ie) { } } } } private synchronized void m4t2() { int i = 5; while(i-- > 0) { System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i); try { Thread.sleep(500); } catch(InterruptedException ie) { } } } // private void m4t2() { // int i = 5; // while(i-- > 0) { // System.out.println(Thread.currentThread().getName() + " : Inner.m4t2()=" + i); // try { // Thread.sleep(500); // } catch(InterruptedException ie) { // } // } // } } private void m4t1(Inner inner) { // synchronized(inner) { //使用对象锁 inner.m4t2(); // } // inner.m4t1(); } private void m4t2(Inner inner) { // synchronized ("i") { inner.m4t2(); // } } public static void main(String[] args) { final Demo1 myt3 = new Demo1(); final Inner inner = myt3.new Inner(); Thread t1 = new Thread( new Runnable() {public void run() { myt3.m4t1(inner);} }, "thread-1"); Thread t2 = new Thread( new Runnable() {public void run() { myt3.m4t2(inner);} }, "thread-2"); t1.start(); t2.start(); } }