1. 两个普通同步方法,先打印邮件还是短信
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 方法
2. sendEmail 方法暂停 3 秒钟,先打印邮件还是短信
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 不会释放锁
3. 新增一个普通的方法 hello,先打印邮件还是短信
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();
}
}
先打印短信,调用普通方法与同步锁无关
4. 两个对象,先打印邮件还是信息
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();
}
}
先打印短信,因为是两个对象,使用的不是同一把锁
5. 同一个对象,两个静态同步方法,先打印邮件还是短信
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 对象
6. 不同的对象,两个静态同步方法,先打印邮件还是短信
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(() -> phone2.sendSMS(), "b").start();
}
}
先打印邮件,同上
7. 一个静态同步方法,一个普通同步方法,先打印邮件还是短信
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,所以静态同步方法与普通同步方法之间是不会有竞态条件的
8. 两个对象,一个静态同步方法,一个普通同步方法,先打印邮件还是短信
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();
}
}
先打印短信,同上