8鎖現(xiàn)象
八鎖->就是關(guān)于鎖的八個(gè)問(wèn)題
鎖是什么,如何判斷鎖的是誰(shuí)
對(duì)象、class模板
深刻理解鎖
鎖的東西無(wú)外乎就兩樣:1、同步方法的調(diào)用者,2、Class模板。
同一個(gè)鎖中,只有當(dāng)前線(xiàn)程資源釋放后才會(huì)被下一個(gè)線(xiàn)程所接手。
同步方法的調(diào)用者是兩個(gè)不同的實(shí)例時(shí),互不相關(guān)。
靜態(tài)同步方法(static)鎖的是整個(gè)Class模板,和同步方法的調(diào)用者也不是同一個(gè)鎖;切Class模板在Java程序中唯一。
代碼示例
1、淺淺理解鎖的作用
同一把鎖中根據(jù)執(zhí)行先后釋放資源,保證一個(gè)資源的使用順序
package org.example.phone;
import java.util.concurrent.TimeUnit;
public class Test1 {
public static void main(String[] args) {
// 標(biāo)準(zhǔn)情況下,打印順序?yàn)?1、發(fā)短信,2、打電話(huà)
// 給sendMsg內(nèi)部延遲四秒執(zhí)行,執(zhí)行順序依舊是 1、發(fā)短信,2、打電話(huà)
// 可知,并非是我們所想的,A線(xiàn)程在前面就先執(zhí)行,而是鎖的機(jī)制導(dǎo)致了這種情況
// phone1只創(chuàng)建了一個(gè)對(duì)象,所以這個(gè)對(duì)象的鎖只有一把,誰(shuí)先拿到就是誰(shuí)先執(zhí)行
// 鎖的對(duì)象是該方法的調(diào)用者,即phone1
Phone1 phone1 = new Phone1();
new Thread(()->{
phone1.sendMsg();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
new Thread(()->{
phone1.call();
},"B").start();
}
}
class Phone1{
// synchronized鎖的對(duì)象是方法的調(diào)用者,Phone1只new了一個(gè)對(duì)象,所以鎖的是new出來(lái)的整個(gè)對(duì)象
public synchronized void sendMsg(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("發(fā)短信");
}
public synchronized void call(){
System.out.println("打電話(huà)");
}
}
2、區(qū)分鎖的對(duì)象
不同的實(shí)例使用的鎖并非同一把,所以也無(wú)法同時(shí)鎖定某個(gè)固定的資源、無(wú)法對(duì)同一資源進(jìn)行有順序的操作
package org.example.phone;
import java.util.concurrent.TimeUnit;
public class Test3 {
public static void main(String[] args) {
// 標(biāo)準(zhǔn)情況下,打印順序?yàn)?1、發(fā)短信,2、打電話(huà)
// 給sendMsg內(nèi)部延遲四秒執(zhí)行,執(zhí)行順序依舊是 1、發(fā)短信,2、打電話(huà)
// 可知,并非是我們所想的,A線(xiàn)程在前面就先執(zhí)行,而是鎖的機(jī)制導(dǎo)致了這種情況
// phone1只創(chuàng)建了一個(gè)對(duì)象,所以這個(gè)對(duì)象的鎖只有一把,誰(shuí)先拿到就是誰(shuí)先執(zhí)行
// 鎖的對(duì)象是該方法的調(diào)用者,即phone1
// 調(diào)用兩個(gè)不同對(duì)象的方法,鎖的是兩個(gè)不同的對(duì)象,此時(shí)先出現(xiàn)打電話(huà),說(shuō)明不同對(duì)象之間的鎖互不影響
Phone3 phone3_1 = new Phone3();
Phone3 phone3_2 = new Phone3();
new Thread(()->{
phone3_1.sendMsg();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
new Thread(()->{
phone3_2.call();
},"B").start();
}
}
class Phone3{
// synchronized鎖的對(duì)象是方法的調(diào)用者,Phone1只new了一個(gè)對(duì)象,所以鎖的是new出來(lái)的整個(gè)對(duì)象
public synchronized void sendMsg(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("發(fā)短信");
}
public synchronized void call(){
System.out.println("打電話(huà)");
}
// 當(dāng)在資源類(lèi)中添加了一個(gè)普通方法后,先輸出hello
// 沒(méi)有鎖,不是同步方法,不受鎖的影響
public void hello(){
System.out.println("Hello");
}
}
3、了解鎖的參與者
只有同步方法參與鎖,普通方法依舊按照java執(zhí)行順序執(zhí)行
package org.example.phone;
import java.util.concurrent.TimeUnit;
public class Test2 {
public static void main(String[] args) {
// 標(biāo)準(zhǔn)情況下,打印順序?yàn)?1、發(fā)短信,2、打電話(huà)
// 給sendMsg內(nèi)部延遲四秒執(zhí)行,執(zhí)行順序依舊是 1、發(fā)短信,2、打電話(huà)
// 可知,并非是我們所想的,A線(xiàn)程在前面就先執(zhí)行,而是鎖的機(jī)制導(dǎo)致了這種情況
// phone1只創(chuàng)建了一個(gè)對(duì)象,所以這個(gè)對(duì)象的鎖只有一把,誰(shuí)先拿到就是誰(shuí)先執(zhí)行
// 鎖的對(duì)象是該方法的調(diào)用者,即phone1
Phone2 phone2 = new Phone2();
new Thread(()->{
phone2.sendMsg();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
new Thread(()->{
phone2.hello();
},"B").start();
}
}
class Phone2{
// synchronized鎖的對(duì)象是方法的調(diào)用者,Phone1只new了一個(gè)對(duì)象,所以鎖的是new出來(lái)的整個(gè)對(duì)象
public synchronized void sendMsg(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("發(fā)短信");
}
public synchronized void call(){
System.out.println("打電話(huà)");
}
// 當(dāng)在資源類(lèi)中添加了一個(gè)普通方法后,先輸出hello
// 沒(méi)有鎖,不是同步方法,不受鎖的影響
public void hello(){
System.out.println("Hello");
}
}
4、明白鎖能鎖誰(shuí)
鎖只能鎖兩個(gè)東西,一個(gè)是同步方法的調(diào)用者,一個(gè)是整個(gè)Class模板(全局唯一),一旦使用static創(chuàng)建靜態(tài)同步方法,那么該方法的鎖鎖的就是全局唯一的Class模板,并且在反射時(shí)就已經(jīng)被創(chuàng)建了
package org.example.phone;
import java.util.concurrent.TimeUnit;
public class Test4 {
public static void main(String[] args) {
// 兩個(gè)對(duì)象的Class類(lèi)模板只有一個(gè);static,鎖的是Class
Phone4 phone4_1 = new Phone4();
Phone4 phone4_2 = new Phone4();
new Thread(()->{
phone4_1.sendMsg();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
new Thread(()->{
phone4_2.call();
},"B").start();
}
}
class Phone4{
// synchronized鎖的對(duì)象是方法的調(diào)用者
// 注:增加了static靜態(tài)方法 此時(shí)調(diào)用該方法的就變成了Phone4的反射對(duì)象,全局唯一
// 此時(shí)鎖的就是Class模板了,即不管你有幾個(gè)調(diào)用者,都在同一個(gè)鎖
// static方法類(lèi)一加載就有了!鎖的是Class
public static synchronized void sendMsg(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("發(fā)短信");
}
public static synchronized void call(){
System.out.println("打電話(huà)");
}
}
5、深入理解鎖的是誰(shuí)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-739976.html
靜態(tài)同步方法和普通同步方法在一起使用時(shí),鎖的并非同一對(duì)象,所以打印順序也時(shí)按java的執(zhí)行順序來(lái),并不存在鎖定資源的情況文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-739976.html
package org.example.phone;
import java.util.concurrent.TimeUnit;
/*
* 1、一個(gè)靜態(tài)同步方法,一個(gè)普通同步方法,先打印發(fā)短信還是打電話(huà)
* 兩個(gè)方法一個(gè)鎖的是Class模板,一個(gè)鎖的是調(diào)用者,鎖的不是同一對(duì)象,所以延遲四秒的靜態(tài)同步方法后打印,延遲一秒的普通同步方法先打印
*
* */
public class Test5 {
public static void main(String[] args) {
Phone5 phone5_1 = new Phone5();
// Phone5 phone5_2 = new Phone5();
new Thread(()->{
phone5_1.sendMsg();
},"A").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
new Thread(()->{
phone5_1.call();
},"B").start();
}
}
class Phone5{
// 鎖的是Class模板
public static synchronized void sendMsg(){
try {
TimeUnit.SECONDS.sleep(4);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.println("發(fā)短信");
}
// 鎖的是調(diào)用者
public synchronized void call(){
System.out.println("打電話(huà)");
}
}
到了這里,關(guān)于JUC并發(fā)編程學(xué)習(xí)筆記(四)8鎖現(xiàn)象的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!