8锁问题什么是锁？锁的对象是谁？package com.sw.lock8; import java.util.concurrent.TimeUnit; /** * @Author suaxi * @Date 2021/1/4 15:44 * 1、执行顺序：发短信 打电话 * 2、增加睡眠时间后，执行顺序：发短信 打电话 */ public class Test1 { public static void main(String[] args) { Phone1 phone1 = new Phone1(); new Thread(() ->{ phone1.sms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() ->{ phone1.call(); },"B").start(); } } class Phone1{ //synchronized锁的对象是方法的调用者 //两个方法用的是同一个锁，谁先拿到锁，谁先调用 public synchronized void sms(){ try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public synchronized void call(){ System.out.println("打电话"); } }package com.sw.lock8; import java.util.concurrent.TimeUnit; /** * @Author suaxi * @Date 2021/1/4 15:51 * 3、增加一个hello的普通方法后，执行顺序为 hello 发短信 * 4、两个对象、两个同步方式，执行顺序为 打电话 发短信 */ public class Test2 { public static void main(String[] args) { //两个对象、两个调用者、两把锁 Phone2 phone1 = new Phone2(); Phone2 phone2 = new Phone2(); new Thread(() ->{ phone1.sms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() ->{ phone2.call(); },"B").start(); } } class Phone2{ //synchronized锁的对象是方法的调用者 public synchronized void sms(){ try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public synchronized void call(){ System.out.println("打电话"); } //普通方法不受锁的限制 public void hello(){ System.out.println("hello"); } }package com.sw.lock8; import java.util.concurrent.TimeUnit; /** * @Author suaxi * @Date 2021/1/4 15:58 * 5、增加static后，执行顺序为 发短信 打电话 * 6、两个Phone对象，执行顺序依然为为 发短信 打电话 */ public class Test3 { public static void main(String[] args) { //两个对象的Class类模板只有一个，与问题5一样锁的也是Class Phone3 phone = new Phone3(); Phone3 phone1 = new Phone3(); new Thread(() ->{ phone.sms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() ->{ phone1.call(); },"B").start(); } } class Phone3{ //synchronized锁的对象是方法的调用者 //static静态方法，类一加载就有了，此处锁的是Class对象 public static synchronized void sms(){ try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public static synchronized void call(){ System.out.println("打电话"); } }package com.sw.lock8; import java.util.concurrent.TimeUnit; /** * @Author suaxi * @Date 2021/1/4 16:05 * 7、1个静态同步方法，1个普通同步方法，一个对象，执行顺序 打电话 发短信 * 8、1个静态同步方法，1个普通同步方法，两个对象，执行顺序 打电话 发短信 */ public class Test4 { public static void main(String[] args) { //两个对象的Class类模板只有一个，与问题5一样锁的也是Class Phone4 phone1 = new Phone4(); Phone4 phone2 = new Phone4(); new Thread(() ->{ phone1.sms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() ->{ phone2.call(); },"B").start(); } } class Phone4{ //静态同步方法 锁的是Class类模板 public static synchronized void sms(){ try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } //普通同步方法 锁的是调用者，不需要再等待发短信的sleep睡眠时间，两个方法用的不是同一个锁 public synchronized void call(){ System.out.println("打电话"); } }小结一个对象，拿的是同一把锁两个对象拿的是不同的锁加了static静态方法之后，不论有几个对象，锁的只有一个Class模板普通方法不受锁的限制