有趣的8锁问题

话不多说,直接上代码

//资源类
class Phone{	
	//同步方法
    public synchronized void email() throws InterruptedException {
        System.out.println("email....");
    }
    //同步方法
    public synchronized void sms() throws InterruptedException {
        System.out.println("Sms....");
    }
}

测试类,定义两个线程

public class Test {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        new Thread(()->{
            try {
                phone.email();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },“A”).start();
        new Thread(()->{
            try {
                phone.sms();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },“B”).start();
    }
}

打印的是什么

email....
Sms....

结论:锁的是this,也就是方法的调用者。
解释:当A线程调用Email方法,会获得锁,也就是当前对象,此时B线程没办法得到锁,就只有等待,直到A线程释放锁。所以打印email,sms

接下来看看这个

class Phone{
    //静态同步方法
    public static synchronized void email() throws InterruptedException {
        TimeUnit.SECONDS.sleep(4);
        System.out.println("email....");
    }
    //同步方法
    public synchronized void sms() throws InterruptedException {
        System.out.println("Sms....");
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        new Thread(()->{
            try {
                Phone.email();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        new Thread(()->{
            try {
                phone.sms();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}
Sms....
email....

解释:当A线程调用email方法,因为是静态的,锁的是class对象,B线程锁的是实例对象,所不一样,所以互不影响。但是A线程睡了4秒,所以打印sms,email

接下来看看这个

class Phone{
    public  synchronized void email() throws InterruptedException {
        //TimeUnit.SECONDS.sleep(4);
        System.out.println("email....");
    }
    public  synchronized void sms() throws InterruptedException {
        System.out.println("Sms....");
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        Phone phone1 = new Phone();
        new Thread(()->{
            try {
                phone.email();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        new Thread(()->{
            try {
                phone1.sms();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}
email....
Sms....

解释:当A线程调用email方法,锁的是phone对象,B线程锁的是phone1对象,锁不一样,所以互不影响。所以打印sms,email

接下来看看这个

class Phone{
    public  synchronized void email() throws InterruptedException {
        //TimeUnit.SECONDS.sleep(4);
        System.out.println("email....");
    }
    public  synchronized void sms() throws InterruptedException {
        System.out.println("Sms....");
    }
    public  void hello() {
        System.out.println("hello....");
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        new Thread(()->{
            try {
                phone.email();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        new Thread(()->{phone.hello();}).start();
    }
}
email....
hello....

解释:当A线程调用email方法,锁的是phone对象,B线程没有加锁,所以互不影响。所以打email,hello

接下来看看这个

class Phone{
    public static synchronized void email() throws InterruptedException {
        //TimeUnit.SECONDS.sleep(4);
        System.out.println("email....");
    }
    public static synchronized void sms() throws InterruptedException {
        System.out.println("Sms....");
    }
}
public class Test {
    public static void main(String[] args) throws Exception {
        Phone phone = new Phone();
        Phone phone1 = new Phone();

        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(4);
                phone.email();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();

        new Thread(()->{phone1.sms();}).start();
    }
}

解释:当A线程调用email方法,锁的是class对象,B线程sms方法,锁的是class对象,是同一个对象。所以打email,sms

是不是很有趣啊~~~~~哈哈

猜你喜欢

转载自blog.csdn.net/qq_42224683/article/details/107306326