/**
* @Description: 8 锁
*
1 标准访问,先打印短信还是邮件
------sendSMS
------sendEmail
2 停 4 秒在短信方法内,先打印短信还是邮件
------sendSMS
------sendEmail
3 新增普通的 hello 方法,是先打短信还是 hello
------getHello
------sendSMS
4 现在有两部手机,先打印短信还是邮件
------sendEmail
------sendSMS
5 两个静态同步方法,1 部手机,先打印短信还是邮件
------sendSMS
------sendEmail
6 两个静态同步方法,2 部手机,先打印短信还是邮件
------sendSMS
------sendEmail
7 1 个静态同步方法,1 个普通同步方法,1 部手机,先打印短信还是邮件
------sendEmail
------sendSMS
8 1 个静态同步方法,1 个普通同步方法,2 部手机,先打印短信还是邮件
------sendEmail
------sendSMS
标准访问,先打印短信还是邮件
import java.util.concurrent.TimeUnit;public class Test {public static void main(String[] args) throws InterruptedException {Phone phone = new Phone();new Thread(()->{try {phone.sendSMS();} catch (Exception e) {e.printStackTrace();}},"AA").start();//因为.start()什么时候创建不确定,所以为了演示八锁的问题,这里睡100毫秒TimeUnit.MILLISECONDS.sleep(100);new Thread(()->{try {phone.sendEmail();} catch (Exception e) {e.printStackTrace();}},"BB").start();TimeUnit.SECONDS.sleep(2);}
}
class Phone {public synchronized void sendSMS() throws Exception {//停留 4 秒
// TimeUnit.SECONDS.sleep(4);System.out.println("------sendSMS");}public synchronized void sendEmail() throws Exception {System.out.println("------sendEmail");}public void getHello() {System.out.println("------getHello");}
}
说明:这种情况锁的对象是this,既phone实例
停 4 秒在短信方法内,先打印短信还是邮件
import java.util.concurrent.TimeUnit;public class Test {public static void main(String[] args) throws InterruptedException {Phone phone = new Phone();new Thread(()->{try {phone.sendSMS();} catch (Exception e) {e.printStackTrace();}},"AA").start();//因为.start()什么时候创建不确定,所以为了演示八锁的问题,这里睡100毫秒TimeUnit.MILLISECONDS.sleep(100);new Thread(()->{try {phone.sendEmail();} catch (Exception e) {e.printStackTrace();}},"BB").start();TimeUnit.SECONDS.sleep(2);}
}
class Phone {public synchronized void sendSMS() throws Exception {//停留 4 秒TimeUnit.SECONDS.sleep(4);System.out.println("------sendSMS");}public synchronized void sendEmail() throws Exception {System.out.println("------sendEmail");}public void getHello() {System.out.println("------getHello");}
}
说明:这种情况锁的对象是this,既phone实例
新增普通的 hello 方法,是先打短信还是 hello
import java.util.concurrent.TimeUnit;public class Test {public static void main(String[] args) throws InterruptedException {Phone phone = new Phone();new Thread(()->{try {phone.sendSMS();} catch (Exception e) {e.printStackTrace();}},"AA").start();//因为.start()什么时候创建不确定,所以为了演示八锁的问题,这里睡100毫秒TimeUnit.MILLISECONDS.sleep(100);new Thread(()->{try {
// phone.sendEmail();phone.getHello();} catch (Exception e) {e.printStackTrace();}},"BB").start();TimeUnit.SECONDS.sleep(2);}
}
class Phone {public synchronized void sendSMS() throws Exception {//停留 4 秒TimeUnit.SECONDS.sleep(4);System.out.println("------sendSMS");}public synchronized void sendEmail() throws Exception {System.out.println("------sendEmail");}public void getHello() {System.out.println("------getHello");}
}
说明:getHello方法是普通方法所以它先执行
现在有两部手机,先打印短信还是邮件
import java.util.concurrent.TimeUnit;public class Test {public static void main(String[] args) throws InterruptedException {Phone phone = new Phone();Phone phone2 = new Phone();new Thread(()->{try {phone.sendSMS();} catch (Exception e) {e.printStackTrace();}},"AA").start();//因为.start()什么时候创建不确定,所以为了演示八锁的问题,这里睡100毫秒TimeUnit.MILLISECONDS.sleep(100);new Thread(()->{try {
// phone.sendEmail();
// phone.getHello();phone2.sendEmail();} catch (Exception e) {e.printStackTrace();}},"BB").start();TimeUnit.SECONDS.sleep(2);}
}
class Phone {public synchronized void sendSMS() throws Exception {//停留 4 秒TimeUnit.SECONDS.sleep(4);System.out.println("------sendSMS");}public synchronized void sendEmail() throws Exception {System.out.println("------sendEmail");}public void getHello() {System.out.println("------getHello");}
}
说明:两部手机就是两个实例对象,是两把锁(phone、phone2),所以互不影响,但是因为 sendSMS等了4秒,所以sendEmail先输出,4秒后 sendSMS再输出
两个静态同步方法,1 部手机,先打印短信还是邮件
import java.util.concurrent.TimeUnit;public class Test {public static void main(String[] args) throws InterruptedException {Phone phone = new Phone();Phone phone2 = new Phone();new Thread(()->{try {phone.sendSMS();} catch (Exception e) {e.printStackTrace();}},"AA").start();//因为.start()什么时候创建不确定,所以为了演示八锁的问题,这里睡100毫秒TimeUnit.MILLISECONDS.sleep(100);new Thread(()->{try {phone.sendEmail();
// phone.getHello();
// phone2.sendEmail();} catch (Exception e) {e.printStackTrace();}},"BB").start();TimeUnit.SECONDS.sleep(2);}
}
class Phone {public static synchronized void sendSMS() throws Exception {//停留 4 秒TimeUnit.SECONDS.sleep(4);System.out.println("------sendSMS");}public static synchronized void sendEmail() throws Exception {System.out.println("------sendEmail");}public void getHello() {System.out.println("------getHello");}
}
说明:static修饰的方法,锁的对象都是Class,所以它们都是同一把锁 Phone
两个静态同步方法,2 部手机,先打印短信还是邮件
import java.util.concurrent.TimeUnit;public class Test {public static void main(String[] args) throws InterruptedException {Phone phone = new Phone();Phone phone2 = new Phone();new Thread(()->{try {phone.sendSMS();} catch (Exception e) {e.printStackTrace();}},"AA").start();//因为.start()什么时候创建不确定,所以为了演示八锁的问题,这里睡100毫秒TimeUnit.MILLISECONDS.sleep(100);new Thread(()->{try {
// phone.sendEmail();
// phone.getHello();phone2.sendEmail();} catch (Exception e) {e.printStackTrace();}},"BB").start();TimeUnit.SECONDS.sleep(2);}
}
class Phone {public static synchronized void sendSMS() throws Exception {//停留 4 秒TimeUnit.SECONDS.sleep(4);System.out.println("------sendSMS");}public static synchronized void sendEmail() throws Exception {System.out.println("------sendEmail");}public void getHello() {System.out.println("------getHello");}
}
说明:static修饰的方法,锁的对象都是Class,所以它们都是同一把锁 Phone
1 个静态同步方法,1 个普通同步方法,1 部手机,先打印短信还是邮件
import java.util.concurrent.TimeUnit;public class Test {public static void main(String[] args) throws InterruptedException {Phone phone = new Phone();Phone phone2 = new Phone();new Thread(()->{try {phone.sendSMS();} catch (Exception e) {e.printStackTrace();}},"AA").start();//因为.start()什么时候创建不确定,所以为了演示八锁的问题,这里睡100毫秒TimeUnit.MILLISECONDS.sleep(100);new Thread(()->{try {phone.sendEmail();
// phone.getHello();
// phone2.sendEmail();} catch (Exception e) {e.printStackTrace();}},"BB").start();TimeUnit.SECONDS.sleep(2);}
}
class Phone {public static synchronized void sendSMS() throws Exception {//停留 4 秒TimeUnit.SECONDS.sleep(4);System.out.println("------sendSMS");}public synchronized void sendEmail() throws Exception {System.out.println("------sendEmail");}public void getHello() {System.out.println("------getHello");}
}
说明:静态同步方法锁的是Class类,而普通同步方法是this对象,所以它们用的不是一把锁
这里sendSMS锁的是Phone,而sendEmail锁的是phone实例
1 个静态同步方法,1 个普通同步方法,2 部手机,先打印短信还是邮件
import java.util.concurrent.TimeUnit;public class Test {public static void main(String[] args) throws InterruptedException {Phone phone = new Phone();Phone phone2 = new Phone();new Thread(()->{try {phone.sendSMS();} catch (Exception e) {e.printStackTrace();}},"AA").start();//因为.start()什么时候创建不确定,所以为了演示八锁的问题,这里睡100毫秒TimeUnit.MILLISECONDS.sleep(100);new Thread(()->{try {
// phone.sendEmail();
// phone.getHello();phone2.sendEmail();} catch (Exception e) {e.printStackTrace();}},"BB").start();TimeUnit.SECONDS.sleep(2);}
}
class Phone {public static synchronized void sendSMS() throws Exception {//停留 4 秒TimeUnit.SECONDS.sleep(4);System.out.println("------sendSMS");}public synchronized void sendEmail() throws Exception {System.out.println("------sendEmail");}public void getHello() {System.out.println("------getHello");}
}
说明:静态同步方法锁的是Class类,而普通同步方法是this对象,所以它们用的不是一把锁
这里sendSMS锁的是Phone,而sendEmail锁的是phone2实例
总结:
具体表现为以下 3 种形式。
对于普通同步方法,锁是当前实例对象。
对于静态同步方法,锁是当前类的 Class 对象。
对于同步方法块,锁是 Synchonized 括号里配置的对象