synchronized关键字浅谈

我的总结:
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();
        }
相关文章
相关标签/搜索