JUC-Lock的8锁问题
Lock的8锁问题,即关于锁的8个问题,以下共展示了8种情况下的8个问题,更有利于理解锁的这个概念
-
标准情况下,两个线程先打印发短信还是打电话?
import java.util.concurrent.TimeUnit; public class Lock1 { public static void main(String[] args) { Phone1 phone = new Phone1(); new Thread(()->{ phone.sendSms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->{ phone.call(); },"B").start(); } } class Phone1{ public synchronized void sendSms(){ System.out.println("发短信"); } public synchronized void call(){ System.out.println("打电话"); } }
-
发短信延迟4秒,两个线程先打印发短信还是打电话?
import java.util.concurrent.TimeUnit; public class Lock2 { public static void main(String[] args) { Phone2 phone = new Phone2(); //锁的存在 new Thread(()->{ phone.sendSms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->{ phone.call(); },"B").start(); } } class Phone2{ public synchronized void sendSms(){ try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public synchronized void call(){ System.out.println("打电话"); } }
以上例子表明,普通的同步方法锁的是new出来的对象,同一个对象调用的两个方法,谁先拿到谁先执行
-
普通方法和普通的同步方法,先执行发短信还是hello?
import java.util.concurrent.TimeUnit; public class Lock3{ public static void main(String[] args) { Phone3 phone = new Phone3(); new Thread(()->{ phone.sendSms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->{ phone.hello(); },"B").start(); } } class Phone3{ public synchronized void sendSms(){ try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public synchronized void call(){ System.out.println("打电话"); } public void hello(){ System.out.println("hello"); } }
-
两个对象,两个同步方法,发短信还是打电话?
import java.util.concurrent.TimeUnit; public class Lock4{ public static void main(String[] args) { Phone4 phone1 = new Phone4(); Phone4 phone2 = new Phone4(); new Thread(()->{ phone1.sendSms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->{ phone2.call(); },"B").start(); } } class Phone4{ public synchronized void sendSms(){ try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public synchronized void call(){ System.out.println("打电话"); } public void hello(){ System.out.println("hello"); } }
-
两个静态的同步方法,只有一个对象,先打印发短信还是打电话?
import java.util.concurrent.TimeUnit; public class Lock5 { public static void main(String[] args) { Phone5 phone = new Phone5(); new Thread(()->{ phone.sendSms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->{ phone.call(); },"B").start(); } } class Phone5{ public static synchronized void sendSms(){ try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public static synchronized void call(){ System.out.println("打电话"); } }
-
两个对象,两个静态的同步方法,先打印发短信还是打电话?
import java.util.concurrent.TimeUnit; public class Lock6 { public static void main(String[] args) { Phone6 phone1 = new Phone6(); Phone6 phone2 = new Phone6(); new Thread(()->{ phone1.sendSms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->{ phone2.call(); },"B").start(); } } class Phone6{ public static synchronized void sendSms(){ try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public static synchronized void call(){ System.out.println("打电话"); } }
-
1个静态的同步方法,1个普通的同步方法,只有一个对象,先打印发短信还是打电话?
import java.util.concurrent.TimeUnit; public class Lock7 { public static void main(String[] args) { Phone7 phone = new Phone7(); new Thread(()->{ phone.sendSms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->{ phone.call(); },"B").start(); } } class Phone7{ public static synchronized void sendSms(){ try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public synchronized void call(){ System.out.println("打电话"); } }
-
1个静态的同步方法,1个普通的同步方法,两个对象,先打印发短信还是打电话?
import java.util.concurrent.TimeUnit; public class Lock8 { public static void main(String[] args) { Phone8 phone1 = new Phone8(); Phone8 phone2 = new Phone8(); new Thread(()->{ phone1.sendSms(); },"A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(()->{ phone2.call(); },"B").start(); } } class Phone8{ public static synchronized void sendSms(){ try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("发短信"); } public synchronized void call(){ System.out.println("打电话"); } }
总结
锁有两种,一种通过new对象,锁的是调用者,另一种通过static修饰的静态方法,锁的是Class,这是全局唯一的一个模板