/**
* @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 括号里配置的对象