梳理对Java的synchronized的理解

移动开发 waitig 377℃ 百度已收录 0评论

Java的synchronized分为对象锁和类锁。
  1、当多个并发线程访问同一个对象object中的这个synchronized(this)代码块时,一个时间内针对该对象的操作只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。
  2、但是,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
  3、当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对该object中所有其它synchronized(this)代码块的访问将被阻塞。
  4、同步加锁的是对象,而不是代码。因此,如果你的类中有一个同步方法,这个方法可以被两个不同的线程同时执行,只要每个线程自己创建一个的该类的实例即可。
  5、不同的对象实例的synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法。
  6、synchronized关键字是不能继承的,也就是说,基类的方法synchronized f(){} 在继承类中并不自动是synchronized f(){},而是变成了f(){}。继承类需要你显式的指定它的某个方法为synchronized方法。
  7、对一个全局对象或者类加锁时,对该类的所有对象都起作用。
  
  
普通方法:
方法A 和方法B同时执行

public class MyObject {
    public  void  methodA(){
        for (int i = 0; i <5 ; i++) {
            System.out.println("methodA -->"+ i);
        }
    }
    public  void  methodB(){
        for (int i = 0; i <5 ; i++) {
            System.out.println("methodB -->"+ i);
        }
    }
}
public class ThreadA extends Thread {
    private MyObject object;

    public ThreadA(MyObject object) {
        this.object = object;
    }
    @Override
    public void run() {
        super.run();
        object.methodA();
    }
}
public class ThreadB extends Thread {
    private MyObject object;
    public ThreadB(MyObject object) {
        this.object = object;
    }

    @Override
    public void run() {
        super.run();
        object.methodB();
    }

}

public class Test  {

    public static void main(String[] args) {
        MyObject object = new MyObject();
        //线程A与线程B 持有的是同一个对象:object
        ThreadA a = new ThreadA(object);
        ThreadB b = new ThreadB(object);
        a.start();
        b.start();
    }
}

执行结果

methodA -->0
methodB -->0
methodB -->1
methodB -->2
methodB -->3
methodB -->4
methodA -->1
methodA -->2
methodA -->3
methodA -->4

加了synchronized之后

public class MyObject {


    synchronized   public  void  methodA(){

        for (int i = 0; i <5 ; i++) {
            System.out.println("methodA -->"+ i);
        }
    }

    synchronized  public  void  methodB(){

        for (int i = 0; i <5 ; i++) {
            System.out.println("methodB -->"+ i);
        }
    }
}

执行结果

methodB -->0
methodB -->1
methodB -->2
methodB -->3
methodB -->4
methodA -->0
methodA -->1
methodA -->2
methodA -->3
methodA -->4

MyObject类中定义有多个synchronized修饰的实例方法时,若多个线程拥有同一个MyObject类的对象,则这些方法只能以同步的方式执行。即,执行完一个synchronized修饰的方法后,才能执行另一个synchronized修饰的方法。

但可以访问非synchronzied方法。
eg:

public class MyObject {
    synchronized   public  void  methodA(){
        for (int i = 0; i <5 ; i++) {
            System.out.println("methodA -->"+ i);
        }
    }

      public  void  methodB(){

        for (int i = 0; i <5 ; i++) {
            System.out.println("methodB -->"+ i);
        }
    }
   }
public class Test  {

    public static void main(String[] args) {
        MyObject object = new MyObject();
        //线程A与线程B 持有的是同一个对象:object,ThreadB执行的是非synchronized方法
        ThreadA a = new ThreadA(object);
        ThreadB b = new ThreadB(object);
        a.start();
        b.start();
    }


}

执行结果

methodA -->0
methodB -->0
methodB -->1
methodB -->2
methodA -->1
methodA -->2
methodA -->3
methodA -->4
methodB -->3
methodB -->4

参考:

https://www.cnblogs.com/cangqiongbingchen/p/5806757.html
https://www.cnblogs.com/hapjin/p/5452663.html


本文由【waitig】发表在等英博客
本文固定链接:梳理对Java的synchronized的理解
欢迎关注本站官方公众号,每日都有干货分享!
等英博客官方公众号
点赞 (0)分享 (0)