彻底理解8锁

彻底理解8锁

重点:锁 锁的是对象或者class模板, 静态方法锁的是class模板

1.初始情况 同一个对象,两个方法加锁,先“打电话”还是发短信?

package com.example.juc;

import java.util.concurrent.TimeUnit;

public class TestLock8 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        new Thread(() -> {
            phone.sendSms();
        }).start();
        TimeUnit.MILLISECONDS.sleep(1);
        new Thread(() -> {
            phone.call();
        }).start();
    }

}

class Phone {
    public synchronized void sendSms() {
        System.out.println("发短信");
    }

    public synchronized void call() {
        System.out.println("打电话");
    }
}

结果:锁的是同一个对象,谁先获得锁,谁就锁住了对象,另一个线程只好先等待

发短信
打电话

2.发短信延迟1s, 同一个对象,两个方法加锁,先“打电话”还是发短信?

package com.example.juc;

import java.util.concurrent.TimeUnit;

public class TestLock8 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        new Thread(() -> {
            phone.sendSms();
        }).start();
        TimeUnit.MILLISECONDS.sleep(1);
        new Thread(() -> {
            phone.call();
        }).start();
    }

}

class Phone {
    public synchronized void sendSms() {
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized void call() {
        System.out.println("打电话");
    }
}

结果:锁的是同一个对象,谁先获得锁,谁就锁住了对象,另一个线程只好先等待

发短信
打电话

3.两个对象,两个方法加锁,先“打电话”还是发短信?

package com.example.juc;

import java.util.concurrent.TimeUnit;

public class TestLock8 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        Phone phone1 = new Phone();
        new Thread(() -> {
            phone.sendSms();
        }).start();
        TimeUnit.MILLISECONDS.sleep(1);
        new Thread(() -> {
            phone1.call();
        }).start();
    }

}

class Phone {
    public synchronized void sendSms() {
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized void call() {
        System.out.println("打电话");
    }
}

结果:锁的是两个不同的对象,所以谁执行的快谁先执行完

打电话
发短信

4.同一个对象,一个方法加锁,一个不加,先“打电话”还是发短信?

package com.example.juc;

import java.util.concurrent.TimeUnit;

public class TestLock8 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        new Thread(() -> {
            phone.sendSms();
        }).start();
        TimeUnit.MILLISECONDS.sleep(1);
        new Thread(() -> {
            phone.call();
        }).start();
    }

}

class Phone {
    public synchronized void sendSms() {
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public void call() {
        System.out.println("打电话");
    }

}

结果:一个线程没有加锁,谁执行的快谁先执行完

打电话
发短信

5.同一个对象,两个静态方法加锁,先“打电话”还是发短信?

package com.example.juc;

import java.util.concurrent.TimeUnit;

public class TestLock8 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        new Thread(() -> {
            phone.sendSms();
        }).start();
        TimeUnit.MILLISECONDS.sleep(1);
        new Thread(() -> {
            phone.call();
        }).start();
    }

}

class Phone {
    public static synchronized void sendSms() {
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public static synchronized void call() {
        System.out.println("打电话");
    }

}

结果:两个线程锁的是同一个class模板,谁先获得锁,谁先执行,另一个只能等待

发短信
打电话

6.两个不同对象,两个静态方法加锁,先“打电话”还是发短信?

package com.example.juc;

import java.util.concurrent.TimeUnit;

public class TestLock8 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        Phone phone1 = new Phone();
        new Thread(() -> {
            phone.sendSms();
        }).start();
        TimeUnit.MILLISECONDS.sleep(1);
        new Thread(() -> {
            phone1.call();
        }).start();
    }

}

class Phone {
    public static synchronized void sendSms() {
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public static synchronized void call() {
        System.out.println("打电话");
    }

}

结果:两个线程锁的是同一个class模板,谁先获得锁,谁先执行,另一个只能等待

发短信
打电话

7.同一个对象,一个静态同步方法,一个非静态同步方法,先“打电话”还是发短信?

package com.example.juc;

import java.util.concurrent.TimeUnit;

public class TestLock8 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        new Thread(() -> {
            phone.sendSms();
        }).start();
        TimeUnit.MILLISECONDS.sleep(1);
        new Thread(() -> {
            phone.call();
        }).start();
    }

}

class Phone {
    public static synchronized void sendSms() {
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized void call() {
        System.out.println("打电话");
    }

}

结果:两个线程锁的不是同一个东西,静态同步方法锁的是class模板,非静态同步方法锁的是对象,互不影响

打电话
发短信

8.两个不同对象,一个静态同步方法,一个非静态同步方法,先“打电话”还是发短信?

package com.example.juc;

import java.util.concurrent.TimeUnit;

public class TestLock8 {
    public static void main(String[] args) throws InterruptedException {
        Phone phone = new Phone();
        Phone phone1 = new Phone();
        new Thread(() -> {
            phone.sendSms();
        }).start();
        TimeUnit.MILLISECONDS.sleep(1);
        new Thread(() -> {
            phone1.call();
        }).start();
    }

}

class Phone {
    public static synchronized void sendSms() {
        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("发短信");
    }

    public synchronized void call() {
        System.out.println("打电话");
    }

}

结果:两个线程锁的不是同一个东西,静态同步方法锁的是class模板,非静态同步方法锁的是对象,互不影响

打电话
发短信
posted @ 2021-11-29 15:40  Oh,mydream!  阅读(88)  评论(0编辑  收藏  举报