个人总结:
synchronized 不可以被继承。synchronized 修饰this,则代表锁住对象,同一个对象互斥。synchronized 修饰XXX.class,则代表锁住字节码,跟锁住同一个类的class的逻辑和static function互斥。synchronized 修饰静态变量,则对于所有具有相同属性值的对象互斥。synchronized 修饰普通变量,则对于同一个对象,在该属性值未变动之前互斥。synchronized 修饰静态方法,则对于所有对象访问该方法互斥。synchronized 修饰普通方法,则对同一个对象访问该方法互斥。1、非static方法synchronized void method1()与void method1(){synchronized(this){}}是等价,都是对象锁,锁定当然对象实例。 2、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异常。
(如果有错误的地方或者没有说明白的地方,请大家指出来,谢谢。)
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(); }