Synchronized 案例
两个普通同步方法,先打印邮件还是短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class Phone { public synchronized void sendEmail() { System.out.println("-------sendEmail"); }
public synchronized void sendSMS() { System.out.println("-------sendSMS"); }
public static void main(String[] args) { Phone phone = new Phone(); new Thread(phone::sendEmail, "a").start(); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(phone::sendSMS, "b").start(); } }
|
先打印邮件,因为一个对象里面如果有多个 synchronized 方法,某一个时刻内,只要一个线程去调用其中的一个 synchronized 方法,其它的线程都只能等待,换句话说,某一个时刻内,只能有唯一的一个线程去访问这些 synchronized 方法,锁的是当前对象 this,被锁定后,其它的线程都不能进入到当前对象的其它的 synchronized 方法
sendEmail 方法暂停 3 秒钟,先打印邮件还是短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class Phone { public synchronized void sendEmail() { try { TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("-------sendEmail"); }
public synchronized void sendSMS() { System.out.println("-------sendSMS"); }
public static void main(String[] args) { Phone phone = new Phone(); new Thread(phone::sendEmail, "a").start(); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(phone::sendSMS, "b").start(); } }
|
先打印邮件,同上,而且 sleep 不会释放锁
新增一个普通的方法 hello,先打印邮件还是短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class Phone { public synchronized void sendEmail() { try { TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("-------sendEmail"); }
public void hello() { System.out.println("-------sendSMS"); }
public static void main(String[] args) { Phone phone = new Phone(); new Thread(phone::sendEmail, "a").start(); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(phone::hello, "b").start(); } }
|
先打印短信,调用普通方法与同步锁无关
两个对象,先打印邮件还是信息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class Phone { public synchronized void sendEmail() { try { TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("-------sendEmail"); }
public synchronized void sendSMS() { System.out.println("-------sendSMS"); }
public static void main(String[] args) { Phone phone = new Phone(); Phone phone2 = new Phone(); new Thread(phone::sendEmail, "a").start(); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(phone2::sendSMS, "b").start(); } }
|
先打印短信,因为是两个对象,使用的不是同一把锁
同一个对象,两个静态同步方法,先打印邮件还是短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class Phone { public static synchronized void sendEmail() { try { TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("-------sendEmail"); }
public static synchronized void sendSMS() { System.out.println("-------sendSMS"); }
public static void main(String[] args) { Phone phone = new Phone(); new Thread(Phone::sendEmail, "a").start(); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(Phone::sendSMS, "b").start(); } }
|
先打印邮件,因为是类锁,锁的是当前类的 Class 对象
不同的对象,两个静态同步方法,先打印邮件还是短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class Phone { public static synchronized void sendEmail() { try { TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("-------sendEmail"); }
public static synchronized void sendSMS() { System.out.println("-------sendSMS"); }
public static void main(String[] args) { Phone phone = new Phone(); Phone phone2 = new Phone(); new Thread(Phone::sendEmail, "a").start(); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(Phone::sendSMS, "b").start(); } }
|
先打印邮件,同上
一个静态同步方法,一个普通同步方法,先打印邮件还是短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class Phone { public static synchronized void sendEmail() { try { TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("-------sendEmail"); }
public synchronized void sendSMS() { System.out.println("-------sendSMS"); }
public static void main(String[] args) { Phone phone = new Phone(); new Thread(Phone::sendEmail, "a").start(); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(phone::sendSMS, "b").start(); } }
|
先打印短信,因为这两把锁是不同的对象,普通同步方法锁的是实例对象 this,静态同步方法锁的是唯一模板 Class,所以静态同步方法与普通同步方法之间是不会有竞态条件的
两个对象,一个静态同步方法,一个普通同步方法,先打印邮件还是短信
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| public class Phone { public static synchronized void sendEmail() { try { TimeUnit.MILLISECONDS.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("-------sendEmail"); } public synchronized void sendSMS() { System.out.println("-------sendSMS"); }
public static void main(String[] args) { Phone phone = new Phone(); Phone phone2 = new Phone(); new Thread(Phone::sendEmail, "a").start(); try { TimeUnit.MILLISECONDS.sleep(300); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(phone2::sendSMS, "b").start(); } }
|
先打印短信,同上