8锁问题

 1 /*
 2 1、标准的访问情况下,先执行 sendEmail 还是 sendSMS
 3 
 4    答案:sendEmail
 5    被 synchronized 修饰的方法,锁的对象是方法的调用者也就是实际new的对象,所以说这里两个方法调用的对象是同一个
 6    先调用的先执行!
 7  */
 8 public class LockDemo01 {
 9     public static void main(String[] args) throws InterruptedException {
10         Phone phone = new Phone();
11 
12         new Thread(()->{
13             phone.sendEmail();
14         },"A").start();
15 
16         //Thread.sleep(200);
17         TimeUnit.SECONDS.sleep(2);
18 
19         new Thread(()->{
20             phone.sendSMS();
21         },"B").start();
22     }
23 }
24 
25 class Phone{
26     public synchronized void sendEmail(){
27         System.out.println("sendEmail");
28     }
29 
30     public synchronized void sendSMS(){
31         System.out.println("sendSMS");
32     }
33 }
 1 /*
 2 2、sendEmail休眠3秒后 ,先执行 sendEmail 还是 sendSMS
 3 
 4    答案:sendEmail
 5    被 synchronized 修饰的方法,锁的对象是方法的调用者,所以说这里两个方法调用的对象是同一个
 6    先调用的先执行!执行sleep()方法的线程并不会释放锁。
 7  */
 8 public class LockDemo02 {
 9     public static void main(String[] args) throws InterruptedException {
10         Phone2 phone = new Phone2();
11 
12         new Thread(()->{
13             try {
14                 phone.sendEmail();
15             } catch (InterruptedException e) {
16                 e.printStackTrace();
17             }
18         },"A").start();
19 
20         //Thread.sleep(200);
21         TimeUnit.SECONDS.sleep(2);
22 
23         new Thread(()->{
24             phone.sendSMS();
25         },"B").start();
26     }
27 }
28 
29 class Phone2{
30     public synchronized void sendEmail() throws InterruptedException {
31         TimeUnit.SECONDS.sleep(3);
32         System.out.println("sendEmail");
33     }
34 
35     public synchronized void sendSMS(){
36         System.out.println("sendSMS");
37     }
38 }
 1 /*
 2 3、增加一个普通方法,请问先打印那个 sendEmail 还是 hello
 3 
 4    答案:hello
 5    新增加的这个方法没有 synchronized 修饰,不是同步方法,不受锁的影响!
 6  */
 7 public class LockDemo03 {
 8     public static void main(String[] args) throws InterruptedException {
 9         Phone3 phone = new Phone3();
10 
11         new Thread(()->{
12             try {
13                 phone.sendEmail();
14             } catch (InterruptedException e) {
15                 e.printStackTrace();
16             }
17         },"A").start();
18 
19         //Thread.sleep(200);
20         TimeUnit.SECONDS.sleep(1);
21 
22         new Thread(()->{
23             phone.hello();
24         },"B").start();
25     }
26 }
27 
28 class Phone3{
29     public synchronized void sendEmail() throws InterruptedException {
30         TimeUnit.SECONDS.sleep(4);
31         System.out.println("sendEmail");
32     }
33 
34     // 没有 synchronized 没有 static 就是普通方式
35     public void hello(){
36         System.out.println("hello");
37     }
38 }
 1 /*
 2 4、两个手机,请问先执行sendEmail 还是 sendSMS
 3     答案:sendSMS
 4     被 synchronized  修饰的方式,锁的对象是调用者;我们这里有两个调用者,两个方法在这里是两个锁
 5  */
 6 public class LockDemo04 {
 7     public static void main(String[] args) throws InterruptedException {
 8         Phone4 phone1 = new Phone4();
 9         Phone4 phone2 = new Phone4();
10 
11         new Thread(()->{
12             try {
13                 phone1.sendEmail();
14             } catch (InterruptedException e) {
15                 e.printStackTrace();
16             }
17         },"A").start();
18 
19         //Thread.sleep(200);
20         TimeUnit.SECONDS.sleep(1);
21 
22         new Thread(()->{
23             phone2.sendSMS();
24         },"B").start();
25     }
26 }
27 
28 class Phone4{
29     public synchronized void sendEmail() throws InterruptedException {
30         TimeUnit.SECONDS.sleep(3);
31         System.out.println("sendEmail");
32     }
33 
34     public synchronized void sendSMS(){
35         System.out.println("sendSMS");
36     }
37 }
 1 /*
 2 5、两个静态同步方法,同一个手机请问先执行sendEmail 还是 sendSMS
 3 
 4     答案:sendEmail
 5     只要方法被 static 修饰,锁的对象就是 Class模板对象,这个则全局唯一!所以说这里是同一个锁
 6     并不是因为synchronized
 7  */
 8 public class LockDemo05 {
 9     public static void main(String[] args) throws InterruptedException {
10         Phone5 phone = new Phone5();
11 
12 
13         new Thread(()->{
14             try {
15                 phone.sendEmail();
16             } catch (InterruptedException e) {
17                 e.printStackTrace();
18             }
19         },"A").start();
20 
21         //Thread.sleep(200);
22         TimeUnit.SECONDS.sleep(1);
23 
24         new Thread(()->{
25             phone.sendSMS();
26         },"B").start();
27     }
28 }
29 
30 class Phone5{
31 
32     public static synchronized void sendEmail() throws InterruptedException {
33         TimeUnit.SECONDS.sleep(3);
34         System.out.println("sendEmail");
35     }
36 
37     public static synchronized void sendSMS(){
38         System.out.println("sendSMS");
39     }
40 
41 }
 1 /*
 2 6、两个静态同步方法,两个手机,请问先执行sendEmail 还是 sendSMS
 3 
 4     答案:sendEmail
 5     只要方法被 static 修饰,锁的对象就是 Class模板对象,这个则全局唯一!所以说这里是同一个锁
 6     并不是因为synchronized
 7  */
 8 public class LockDemo06 {
 9     public static void main(String[] args) throws InterruptedException {
10         Phone6 phone = new Phone6();
11         Phone6 phone2 = new Phone6();
12 
13         new Thread(()->{
14             try {
15                 phone.sendEmail();
16             } catch (InterruptedException e) {
17                 e.printStackTrace();
18             }
19         },"A").start();
20 
21         //Thread.sleep(200);
22         TimeUnit.SECONDS.sleep(1);
23 
24         new Thread(()->{
25             phone2.sendSMS();
26         },"B").start();
27     }
28 }
29 
30 class Phone6{
31 
32     public static synchronized void sendEmail() throws InterruptedException {
33         TimeUnit.SECONDS.sleep(3);
34         System.out.println("sendEmail");
35     }
36 
37     public static synchronized void sendSMS(){
38         System.out.println("sendSMS");
39     }
40 
41 }
 1 /*
 2 7、一个普通同步方法,一个静态同步方法,只有一个手机,请问先执行sendEmail 还是 sendSMS
 3 
 4     答案:sendSMS
 5     synchronized 锁的是这个调用的对象
 6     static 锁的是这个类的Class模板
 7     这里是两个锁!
 8  */
 9 public class LockDemo07 {
10     public static void main(String[] args) throws InterruptedException {
11         Phone7 phone = new Phone7();
12 
13         new Thread(()->{
14             try {
15                 phone.sendEmail();
16             } catch (InterruptedException e) {
17                 e.printStackTrace();
18             }
19         },"A").start();
20 
21         //Thread.sleep(200);
22         TimeUnit.SECONDS.sleep(1);
23 
24         new Thread(()->{
25             phone.sendSMS();
26         },"B").start();
27     }
28 }
29 
30 class Phone7{
31 
32     public static synchronized void sendEmail() throws InterruptedException {
33         TimeUnit.SECONDS.sleep(3);
34         System.out.println("sendEmail");
35     }
36 
37     public synchronized void sendSMS(){
38         System.out.println("sendSMS");
39     }
40 
41 }
 1 /*
 2 8、一个普通同步方法,一个静态同步方法,两个手机,请问先执行sendEmail 还是 sendSMS
 3 
 4     答案:sendSMS
 5     synchronized 锁的是这个调用的对象
 6     static 锁的是这个类的Class模板
 7     这里是两个锁!
 8  */
 9 public class LockDemo08 {
10     public static void main(String[] args) throws InterruptedException {
11         Phone8 phone = new Phone8();
12         Phone8 phone2 = new Phone8();
13 
14         new Thread(()->{
15             try {
16                 phone.sendEmail();
17             } catch (InterruptedException e) {
18                 e.printStackTrace();
19             }
20         },"A").start();
21 
22         //Thread.sleep(200);
23         TimeUnit.SECONDS.sleep(1);
24 
25         new Thread(()->{
26             phone2.sendSMS();
27         },"B").start();
28     }
29 }
30 
31 class Phone8{
32 
33     public static synchronized void sendEmail() throws InterruptedException {
34         TimeUnit.SECONDS.sleep(3);
35         System.out.println("sendEmail");
36     }
37 
38     public synchronized void sendSMS(){
39         System.out.println("sendSMS");
40     }
41 
42 }


小结

1、new this 调用的这个对象,是一个具体的对象!

2、static class 唯一的一个模板!

在我们编写多线程程序得时候,只需要搞明白这个到底锁的是什么就不会出错了!

synchronized(Demo.class){

}//等同于static synchronized 方法
synchronized(this){

}//等同于synchronized普通方法

猜你喜欢

转载自www.cnblogs.com/jk2330/p/12434368.html