synchronized对普通同步方法和对静态方法的区别

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LQM1991/article/details/86143278
synchronized是一个重量级锁,我们都知道该关键字锁住的是对象而不是代码本身,那么对于静态方法和同步方法有什么不同呢,通过如下代码进行测试
public class SynchronizedTest {

    private static int num;

    private synchronized void test(String param){
        if(StringUtils.equals(param,"a")){
            num = 100;
            System.out.println("set " + param + " num over");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else{
            num = 200;
            System.out.println("set " + param + " num over");
        }
        System.out.println("i am : " + param + "; num = " + num);
    }

    public static void main(String[] args){
        SynchronizedTest s1 = new SynchronizedTest();
        SynchronizedTest s2 = new SynchronizedTest();

        new Thread(new Runnable() {
            @Override
            public void run() {
                s1.test("a");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                s2.test("b");
            }
        }).start();
    }
}

输出结果为:


set a num over
set b num over
i am : b; num = 200
i am : a; num = 200

Process finished with exit code 0

我们可以看出两个不同的对象s1和s2并没有互斥,因为这里synchronized是分别持有两个对象的锁。如果要想m1,m2两个对象竞争同一个锁,则需要在method01()上加上static修饰,如下:

public class SynchronizedTest {

    private static int num;

    private synchronized static void test(String param){
        if(StringUtils.equals(param,"a")){
            num = 100;
            System.out.println("set " + param + " num over");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }else{
            num = 200;
            System.out.println("set " + param + " num over");
        }
        System.out.println("i am : " + param + "; num = " + num);
    }

    public static void main(String[] args){
        SynchronizedTest s1 = new SynchronizedTest();
        SynchronizedTest s2 = new SynchronizedTest();

        new Thread(new Runnable() {
            @Override
            public void run() {
                s1.test("a");
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                s2.test("b");
            }
        }).start();
    }
}

运行结果如下:

set a num over
i am : a; num = 100
set b num over
i am : b; num = 200

Process finished with exit code 0

synchronized修饰不加static的方法,锁是加在单个对象上,不同的对象没有竞争关系;修饰加了static的方法,锁是加载类上,这个类所有的对象竞争一把锁.

猜你喜欢

转载自blog.csdn.net/LQM1991/article/details/86143278