Java synchronized的使用

须要明确的几个问题:ide

  • synchronized关键字能够做为函数的修饰符,也可做为函数内的语句,也就是平时说的同步方法和同步语句块。若是 再细的分类,synchronized可做用于instance变量object reference(对象引用)、static函数和class literals(类名称字面常量)身上。
  • 不管synchronized关键字加在方法上仍是对象上,它取得的锁都是对象,而不是把一段代码或函数看成锁――并且同步方法极可能还会被其余线程的对象访问。
  • 每一个对象只有一个锁(lock)与之相关联。
  • 实现同步是要很大的系统开销做为代价的,甚至可能形成死锁,因此尽可能避免无谓的同步控制。

synchronized关键字的做用域有二种:

  1. 某个对象实例内,synchronized aMethod(){}能够防止多个线程同时访问这个对象的synchronized方法(若是一个对象有多个synchronized方法,只要一个线 程访问了其中的一个synchronized方法,其它线程不能同时访问这个对象中任何一个synchronized方法)。这时,不一样的对象实例的 synchronized方法是不相干扰的。也就是说,其它线程照样能够同时访问相同类的另外一个对象实例中的synchronized方法;
  2. 某个类的范围,synchronized static aStaticMethod{}防止多个线程同时访问这个类中的synchronized static 方法。它能够对类的全部对象实例起做用。

 

一、使用在方法上synchronized aMethod(){...}函数

  使用相同的 object测试

public  class synchTest {
    private String a= "";
    private List<String> b= new ArrayList<>();

    // 方法一
    public  void job()  {
        System.out.println("job .....");
        synchronized (b){
            System.out.println("job 使用锁中 ....");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("job end.....");
    }
    // 方法二
    public synchronized void job2(){
        System.out.println("job2 .....");
        synchronized (b){
            System.out.println("job22 使用锁中 ...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("job2 end.....");
    }


    public static void main(String[] args) {
        final synchTest rs = new synchTest();
        new Thread() {
            public void run() {
                rs.job();
            }
        }.start();
        new Thread() {
            public void run() {
                rs.job2();
            }
        }.start();
    }
}

结果:
job .....
job 使用锁中 ....
job2 .....
job end.....
job22 使用锁中 ...
job2 end.....
View Code

     使用不一样的objectthis

public  class synchTest {
    private String a= "";
    private List<String> b= new ArrayList<>();

    // 方法一
    public  void job()  {
        System.out.println("job .....");
        synchronized (a){
            System.out.println("job 使用锁中 ....");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("job end.....");
    }
    // 方法二
    public synchronized void job2(){
        System.out.println("job2 .....");
        synchronized (b){
            System.out.println("job22 使用锁中 ...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("job2 end.....");
    }


    public static void main(String[] args) {
        final synchTest rs = new synchTest();
        new Thread() {
            public void run() {
                rs.job();
            }
        }.start();
        new Thread() {
            public void run() {
                rs.job2();
            }
        }.start();
    }
}

结果:
job .....
job 使用锁中 ....
job2 .....
job22 使用锁中 ...
job end.....
job2 end.....
View Code

    使用this关键词 spa

public  class synchTest {
    private String a= "";
    private List<String> b= new ArrayList<>();

    // 方法一
    public  void job()  {
        System.out.println("job .....");
        synchronized (this){
            System.out.println("job 使用锁中 ....");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("job end.....");
    }
    // 方法二
    public synchronized void job2(){
        System.out.println("job2 .....");
        synchronized (b){
            System.out.println("job22 使用锁中 ...");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("job2 end.....");
    }


    public static void main(String[] args) {
        final synchTest rs = new synchTest();
        new Thread() {
            public void run() {
                rs.job();
            }
        }.start();
        new Thread() {
            public void run() {
                rs.job2();
            }
        }.start();
    }
}

结果:
job .....
job 使用锁中 ....
job end.....
job2 .....
job22 使用锁中 ...
job2 end.....
View Code

  结论:线程

  •   synchronized(Object) object相同的状况下,修饰的内容会同步,等上一个执行完才能执行下一个方法的内容
  •        synchronized(Object) object不相同的状况下,修饰内容不会同步,两个方法能够一块儿执行
  •         this这个比较特殊,若是先执行修饰this这个方法的内容,会同步,不然 不会同步(能够测试下)

二、使用在方法内部 synchronized(Oject){...}3d

public  class synchTest {
    // 方法一
    public synchronized   void job()  {
        System.out.println("job .....");
        System.out.println("job 使用锁中 ....");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        System.out.println("job end.....");
    }
    // 方法二
    public synchronized void job2(){
        System.out.println("job2 .....");
        System.out.println("job22 使用锁中 ...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        System.out.println("job2 end.....");
    }

    public static void main(String[] args) {
        final synchTest rs = new synchTest();
        new Thread() {
            public void run() {
                rs.job();
            }
        }.start();
        new Thread() {
            public void run() {
                rs.job2();
            }
        }.start();
    }
}

结果:
job .....
job 使用锁中 ....
job end.....
job2 .....
job22 使用锁中 ...
job2 end.....
View Code

   结论:code

  • 对象实例内,synchronized aMethod(){}能够防止多个线程同时访问这个对象的synchronized方法,在对象内容全部的synchronized 的方法都会同步,必须等上一个方法执行完才能执行下一个方法

 

二、使用在方法内部 synchronized(Oject){...}、synchronized aMethod(){...}混用对象

public  class synchTest {
    public String a = "";
    // 方法一
    public void job()  {
        System.out.println("job .....");
        synchronized (a){
            System.out.println("job 使用锁中 ....");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
            }
        }
        System.out.println("job end.....");
    }
    // 方法二
    public synchronized void job2(){
        System.out.println("job2 .....");
        System.out.println("job22 使用锁中 ...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
        }
        System.out.println("job2 end.....");
    }

    public static void main(String[] args) {
        final synchTest rs = new synchTest();
        new Thread() {
            public void run() {
                rs.job();
            }
        }.start();
        new Thread() {
            public void run() {
                rs.job2();
            }
        }.start();
    }
}
结果:
job .....
job 使用锁中 ....
job2 .....
job22 使用锁中 ...
job end.....
job2 end.....
View Code

   结论:blog

  对象实例内 synchronized aMethod(){} 与synchronized(Object)  不会相互同步

相关文章
相关标签/搜索