synchronize关键字学习

在平常的开发中多线程肯定是离不开的,而线程同步中有一个很重要的概念就是synchronize。下面我就会对这个关键字进行发表一点我的理解。
synchronize是一种同步锁,他可以有以下几种用法

  • 修饰普通方法
  • 修饰静态方法
  • 修饰代码块

当普通方法被synchronize修饰的时候该对象就被锁住了

public class SynchronizeDemo { 
    private int num = 0;
   synchronized public void add(){
        for (int i = 0; i < 5; i++){
            System.out.println(Thread.currentThread().getName() + "----" + (num++));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
 public static void main(String[] args){
        final SynchronizeDemo synchronizeDemo = new SynchronizeDemo();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizeDemo.add();
            }
        },"test1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizeDemo.add();
            }
        },"test2");

        thread.start();
        thread2.start();
    }

这时就会输出

test1----0
test1----1
test1----2
test1----3
test1----4
test2----5
test2----6
test2----7
test2----8
test2----9

但是像下面这样

public static void main(String[] args){
        final SynchronizeDemo synchronizeDemo1 = new SynchronizeDemo();
        final SynchronizeDemo synchronizeDemo2 = new SynchronizeDemo();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizeDemo1.add();
            }
        },"test1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizeDemo2.add();
            }
        },"test2");

        thread.start();
        thread2.start();
    }

就会输出

test1----0
test2----0
test2----1
test1----1
test1----2
test2----2
test1----3
test2----3
test2----4
test1----4

这是当然的因为synchronize修饰方法时他是对象锁,synchronizeDemo1和synchronizeDemo2是两个不同的对象所以他们并不能同步

public class SynchronizeDemo {
    private int num = 0;
   synchronized public void add(){
        for (int i = 0; i < 5; i++){
            System.out.println(Thread.currentThread().getName() + "----" + (num++));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    public void add2(){
        for (int i = 0; i < 5; i++){
            System.out.println(Thread.currentThread().getName() + "----" + (num++));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
test1----0
test2----1
test2----2
test1----2
test1----4
test2----3
test1----5
test2----6
test1----7
test2----8

不是对象锁吗?为什么这里出现不同步了,那是synchronize只能保证他修饰的方法同步,不同线程可以同时访问没有被synchronize修饰的方法。
synchronize代码块的用法和修饰方法差不多
上面的代码等同于

  public void add(){
        synchronized (this){
            for (int i = 0; i < 5; i++){
                System.out.println(Thread.currentThread().getName() + "----" + (num++));
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

    }

synchronize修饰的代码块同步的就是代码块中的代

 synchronized static public void add(){

        for (int i = 0; i < 5; i++){
            System.out.println(Thread.currentThread().getName() + "----" + (num++));
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

当synchronize修饰的是静态方法时他锁住的就是这个类

public static void main(String[] args){
        final SynchronizeDemo synchronizeDemo1 = new SynchronizeDemo();
        final SynchronizeDemo synchronizeDemo2 = new SynchronizeDemo();
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizeDemo1.add();
            }
        },"test1");
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronizeDemo2.add2();
            }
        },"test2");

        thread.start();
        thread2.start();
    }

你会发现他是同步的,synchronize锁住类之后所以synchronize修饰的方法和方法块将都是同步执行的。这就是synchronize的一些用法

你可能感兴趣的:(synchronize关键字学习)