八锁现象
-
标准情况下,两个线程
public class Lock8test1 { 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("打电话"); } }
发短信->1s->打电话
线程A先拿到锁,线程B再拿到锁 -
sendSms延时
public class Lock8test2 { 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("打电话"); } }
4s->发短信->打电话
线程A先拿到synchronized的锁 -
普通非synchronized方法hello
public class Lock8test3 { public static void main(String[] args) { Phone3 phone = new Phone3(); new Thread(() -> { phone.hello(); }, "A").start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { phone.call(); }, "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"); } }
hello->1s->打电话
普通方法没有拿到锁 -
两个对象
public class Lock8test4 { 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("打电话"); } }
1s->打电话
4s---->发短信
锁的是不同对象,互不影响 -
将Phone的方法设置为static
public class Lock8test5 { 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("打电话"); } }
4s->发短信->打电话
static修饰之后,synchronized锁的是类模版 -
两个对象,两个static方法
public class Lock8test6 { 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("打电话"); } }
4s->发短信->打电话
同上 -
一个对象,一个静态方法,一个普通方法
public class Lock8test7 { 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("打电话"); } }
1s->打电话
4s---->发短信
普通方法中synchronized锁的是对象本身,static方法中synchronized锁的是类模版,所以互不影响 -
两个对象,一个静态方法,一个普通方法
public class Lock8test8 { 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("打电话"); } }
1s->打电话
4s---->发短信
同上