synchronized 到底锁的是谁?

synchronized 到底锁的是谁?
修饰方法:
1、静态方法
2、非静态方法,锁住的是方法的调用者
修饰代码块

1、synchronized修饰非静态方法 锁住的是方法的调用者

锁住实例

流程:
1、线程A先拿到synModel对象然后给这个 synModel对象加上锁–接着等3s执行输出结束
2、线程B等1s后运行,此时 synModel对象 已经被 A拿到,所以他只能等待 等3s后,线程A释放 synModel对象,然后获取对象执行输出结束

public class SynchronizedTest {

    public static void main(String[] args) throws InterruptedException {
        SynModel synModel = new SynModel();
        new Thread(()->{
            synModel.fun1();
        },"A").start();

        TimeUnit.SECONDS.sleep(1);
        new Thread(()->{
            synModel.fun2();
        },"B").start();
    }
}
class SynModel{

    public synchronized void fun1()  {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("1...");
    }
    public synchronized void fun2(){
        System.out.println("2...");
    }
}

情况1 不会排队

注意:下面这种情况是不会排队的,因为锁的是实例。

public class SynchronizedTest {

    public static void main(String[] args) throws InterruptedException {
        SynModel synModel1 = new SynModel();
        SynModel synModel2 = new SynModel();
        new Thread(()->{
            synModel1.fun1();
        },"A").start();

        TimeUnit.SECONDS.sleep(1);
        new Thread(()->{
            synModel2.fun2();
        },"B").start();
    }
}
class SynModel{

    public  synchronized void fun1()  {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("1...");
    }
    public  synchronized void fun2(){
        System.out.println("2...");
    }
}

2 、修饰静态方法

只是把SynModel中的方法变成了静态的,注意此时锁住的是 SynModel这个类,不是锁的实例。会排队 先输出1后输出2

public class SynchronizedTest {

    public static void main(String[] args) throws InterruptedException {
        SynModel synModel1 = new SynModel();
        SynModel synModel2 = new SynModel();
        new Thread(()->{
            synModel1.fun1();
        },"A").start();

        TimeUnit.SECONDS.sleep(1);
        new Thread(()->{
            synModel2.fun2();
        },"B").start();
    }
}
class SynModel{

    public static synchronized void fun1()  {
        try {
            TimeUnit.SECONDS.sleep(3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("1...");
    }
    public static synchronized void fun2(){
        System.out.println("2...");
    }
}

3、代码块

synchronized (this){}锁住的是SynModel这个对象。可以看到循环的五次都是同一个SynModel对象。所以五个线程 某个时刻只能有一个线程拿到这个SynModel对象 这个资源。
每个线程会依次输出start end


public class SynchronizedTest {
    public static void main(String[] args) {
        final SynModel synModel = new SynModel();
        for (int i = 0; i < 5; i++) {
            synModel.fun3();
        }
    }
}
class SynModel{
    public void fun3(){
        synchronized (this){
            System.out.println("start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("end");
        }
    }

}

如果把对象放在循环里面,此时就是五个线程拿五个资源了。并没有去争夺资源

public class SynchronizedTest {
    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            final SynModel synModel = new SynModel();
            new Thread(()->{
                synModel.fun3();
            }).start();
        }
    }
}
class SynModel{
    public void fun3(){
        synchronized (this){
            System.out.println("ThreadName:"+Thread.currentThread().getName()+"start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("ThreadName:"+Thread.currentThread().getName()+"end");
        }
    }

}

锁住SynModel.class 此时五个线程就会竞争,因为锁住的是 SynModel这个类,而不是实例对象了。

public class SynchronizedTest {

    public static void main(String[] args) {
        for (int i = 0; i < 5; i++) {
            final SynModel synModel = new SynModel();
            new Thread(()->{
                synModel.fun3();
            }).start();
        }
    }
}
class SynModel{

  

    public void fun3(){
        synchronized (SynModel.class){// this SynModel.class
            System.out.println("ThreadName:"+Thread.currentThread().getName()+"start");
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("ThreadName:"+Thread.currentThread().getName()+"end");
        }
    }

}

你可能感兴趣的:(java,java)