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