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 }
小结
2、static class 唯一的一个模板!
在我们编写多线程程序得时候,只需要搞明白这个到底锁的是什么就不会出错了!
synchronized(Demo.class){
}//等同于static synchronized 方法
synchronized(this){
}//等同于synchronized普通方法