我的总结:
java
synchronized 不能够被继承。 synchronized 修饰this,则表明锁住对象,同一个对象互斥。 synchronized 修饰XXX.class,则表明锁住字节码,跟锁住同一个类的class的逻辑和static function互斥。 synchronized 修饰静态变量,则对于全部具备相同属性值的对象互斥。 synchronized 修饰普通变量,则对于同一个对象,在该属性值未变更以前互斥。 synchronized 修饰静态方法,则对于全部对象访问该方法互斥。 synchronized 修饰普通方法,则对同一个对象访问该方法互斥。 一、非static方法 synchronized void method1()与void method1(){synchronized(this){}}是等价,都是对象锁,锁定固然对象实例。 二、static方法 static synchronized void method1()与static void method1(){ synchronized (Foo.class){}}是等价,是等价的,锁定Class的字节码。 sleep和wait的区别有: 1,这两个方法来自不一样的类分别是Thread和Object 2,最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其余线程可使用同步控制块或者方法。 3,wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep能够在 任何地方使用 synchronized(x){ x.notify() //或者wait() } 4,sleep必须捕获异常,而wait,notify和notifyAll不须要捕获异常 5,调用sleep()和yield()的时候锁并无被释放,而调用wait()将释放锁。这样另外一个任务(线程)能够得到当前对象的锁, 从而进入它的synchronized方法中。能够经过notify()/notifyAll(),或者时间到期,从wait()中恢复执行。 只能在同步控制方法或同步块中调用wait()、notify()和notifyAll()。 若是在非同步的方法里调用这些方法,在运行时会抛出IllegalMonitorStateException异常。
(若是有错误的地方或者没有说明白的地方,请你们指出来,谢谢。)
ide
Foo 类 class Foo { private String name; private static String desc; private byte[] b = new byte[10]; private static Foo foo; private Foo() { // TODO Auto-generated constructor stub } public static Foo getInstance(){ if(null == foo ){ foo = new Foo(); } return foo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public static String getDesc() { return desc; } public static void setDesc(String desc) { Foo.desc = desc; } public byte[] getB() { return b; } public void setB(byte[] b) { this.b = b; } public synchronized static void methodOne(String flag) { System.out.println("methodOne"+flag); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } public synchronized void methodTwo(String flag) { System.out.println("**methodTwo**"+flag); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } public void methodThrid(String flag){ synchronized (this) { System.out.println("**methodThrid**"+flag); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void methodFour(String flag){ //synchronized锁住属性值,若是对于同一个对象,若是该属性值同样,则会互斥,若是不同的话,则不会互斥。 synchronized (name) { System.out.println("**name**"+flag+name); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void methodFive(String flag){ //synchronized锁住静态属性值,若是这个属性值相同,则互斥,不然不互斥。 synchronized (desc) { System.out.println("**desc**"+flag); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void methodSix(String flag){ synchronized (b) { System.out.println("**b**"+flag+b); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } public void methodSeven(String flag){ //synchronized锁住class的时候,会跟class里面的static function 互斥,不会跟普通function互斥。 synchronized (Foo.class) { System.out.println("**Foo.class**"+flag); try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
main 方法测试程序 for (int i = 0; i < 5; i++) { // start two thread new Thread(new Runnable() { @Override public void run() { Foo f = Foo.getInstance(); f.setName("tttt"); //Foo.setDesc("ooo"); //f.methodTwo(Thread.currentThread().getName()); //Foo.methodOne(Thread.currentThread().getName()); //f.methodFour(Thread.currentThread().getName()); //f.methodFive(Thread.currentThread().getName()); //f.methodSeven(Thread.currentThread().getName()); f.methodSix(Thread.currentThread().getName()); } }).start(); new Thread(new Runnable() { @Override public void run() { Foo f = Foo.getInstance(); f.setName("pppp"); //Foo.setDesc("zzz"); //f.methodTwo(Thread.currentThread().getName()); //f.methodThrid(Thread.currentThread().getName()); //f.methodFour(Thread.currentThread().getName()); //Foo.methodOne(Thread.currentThread().getName()); //f.methodFive(Thread.currentThread().getName()); //f.methodSeven(Thread.currentThread().getName()); //f.methodSix(Thread.currentThread().getName()); } }).start(); }