大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學習攻略 Java學習 Java高并發編程詳解

Java高并發編程詳解

更新時間:2022-08-08 12:19:31 來源:動力節點 瀏覽1238次

Java教程中,高并發編程是一定要學習的,下面動力節點小編來為大家進行介紹。

This Monitor和Class Monitor的詳細介紹

synchronized同步類的不同實例方法,爭搶的是同一個monitor的lock,而與之關聯的引用是ThisMonitor的實例引用

package JavaConcurrencyInPractice.book.charpter3;
import java.util.concurrent.TimeUnit;
/**
 * @program: JavaLife
 * @author: JiaLe Hu
 * @create: 2020-12-09 10:38
 **/
public class ThisMonitor {
    public synchronized void method1() {
        System.out.println(Thread.currentThread().getName() + "enter to method1");
        try {
            TimeUnit.MINUTES.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    public void method2() {
        synchronized (this) {
            System.out.println(Thread.currentThread().getName() + "enter to method1");
            try {
                TimeUnit.MINUTES.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
//    public synchronized void method2() {
//        System.out.println(Thread.currentThread().getName() + "enter to method2");
//        try {
//            TimeUnit.MINUTES.sleep(10);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//    }
    public static void main(String[] args) {
        ThisMonitor thisMonitor = new ThisMonitor();
        new Thread(thisMonitor::method1, "T1").start();
        new Thread(thisMonitor::method2, "T2").start();
    }
}

synchronized同步某個類的不同靜態方法爭搶的鎖也是同一個monitor的lock,該monitor關聯的引用是ClassMonitor.class實例

package JavaConcurrencyInPractice.book.charpter3;
import java.util.concurrent.TimeUnit;
/**
 * @program: JavaLife
 * @author: JiaLe Hu
 * @create: 2020-12-09 10:49
 **/
public class ClassMonitor {
    public static synchronized void method1() {
        System.out.println(Thread.currentThread().getName() + "enter to method1");
        try {
            TimeUnit.MINUTES.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
//    public static synchronized void method2() {
//        System.out.println(Thread.currentThread().getName() + "enter to method1");
//        try {
//            TimeUnit.MINUTES.sleep(10);
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
//    }
    public static synchronized void method2() {
        synchronized (ClassMonitor.class) {
            System.out.println(Thread.currentThread().getName() + "enter to method1");
            try {
                TimeUnit.MINUTES.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

重入

內置鎖是可以重入的,如果某個線程試圖獲得一個已經由它自己持有的鎖,那么這個請求就會成功。重入意味著獲取鎖的操作的粒度是線程。

Wait And notify

wait 方法是可中斷的,當前線程一旦調用了wait方法進入阻塞狀態,其他線程是可以使用interrupt方法將其打斷。

線程執行了某個對象的wait方法,會加入與之對應的wait set中,每一個對象的monitor都有一個與之關聯的wait set

必須在同步方法中使用wait和notify,因為執行wait和notify的前提條件是必須持有同步方法的monitor的所有權

wait會釋放掉monitor的鎖

synchronized 的缺陷

不能控制阻塞的時間

同步方法不能被中斷,不能像wait和sleep方法一樣,能夠捕獲得到中斷信號

package LeetCode;
import java.util.concurrent.TimeUnit;
/**
 * @program: JavaLife
 * @author: JiaLe Hu
 * @create: 2020-12-10 09:32
 **/
public class synchronizedDefect {
    public synchronized void syncMethod() {
        try {
            System.out.println(Thread.currentThread().getName() + " get this monitor");
            TimeUnit.HOURS.sleep(1);
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() + " is interrupted");
        }
    }
    public static void main(String[] args) throws InterruptedException {
        synchronizedDefect synchronizedDefect = new synchronizedDefect();
        Thread t1 = new Thread(synchronizedDefect::syncMethod, "t1");
        t1.start();
        TimeUnit.MILLISECONDS.sleep(2);
        Thread t2 = new Thread(synchronizedDefect::syncMethod, "t2");
        t2.start();
        TimeUnit.MILLISECONDS.sleep(2);
        t2.interrupt();
        System.out.println(t2.isInterrupted()); // true
        System.out.println(t2.getState()); // BLOCKED
    }
}

Hook函數

該ThreadGroup如果有父ThreadGroup,則直接調用父Group的uncaughtException方法

如果設置了全局默認的UncaughtException,則會調用全局的uncaughtException方法

若既沒有父ThreadGroup,也沒有全局默認的UncaughtException,直接將異常的堆棧信息定向到System.err中

Hook注入(Runtime)

package JavaConcurrencyInPractice.book.charpter4;
import java.util.concurrent.TimeUnit;
/**
 * @program: JavaLife
 * @author: JiaLe Hu
 * @create: 2020-12-11 11:05
 **/
public class ThreadHook {
    public static void main(String[] args) {
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                System.out.println("The hook thread 1 is running ");
                TimeUnit.SECONDS.sleep(1);
                System.out.println("The hook thread 1 will exit");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }));
        Runtime.getRuntime().addShutdownHook(new Thread(() -> {
            try {
                System.out.println("The hook thread 2 is running ");
                TimeUnit.SECONDS.sleep(2);
                System.out.println("The hook thread 2 will exit");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }));
        System.out.println("program is exiting");
    }
}

Hook線程應用場景以及注意事項

Hook線程只有在收到推出信號的時候會被執行,如果在kill的時候使用了參數-9,那么Hook線程不會執行,進程將立即退出,因此lock文件不會被刪除

Hook線程中也可以執行一些資源釋放的工作,比如關閉文件句柄、socket鏈接、數據庫connection

盡量不要在Hook線程中執行一些耗時非常長的操作。因此會導致程序遲遲不能退出。

類加載的過程

使用new關鍵字會導致類的初始化

訪問類的靜態變量

訪問類的靜態方法,會導致類的初始化

對某個類進行反射

初始化子類會導致父類的初始化(通過子類的靜態變量只會導致父類的初始化)

啟動類

除了上述的6種情況,其余都被稱為被動使用,不會導致類的加載和初始化

類的加載階段

class文件種的二進制數據讀取到內存中,然后將該字節流所代表的靜態存儲結構轉換為方法區中的運行時的數據結構,并且在堆內存中生成一個該類的java.lang.Class對象,作為訪問方法區數據結構的入口。加載過程常伴隨著連接階段交叉工作。

類初始化的階段

包含了所有類變量的賦值動作和靜態語句塊的執行代碼

靜態語句塊只能對后面的靜態變量進行賦值,但是不能對其訪問。父類的靜態變量總是能夠得到優先賦值。

JVM內置三大加載器

根加載器

根加載器又被稱為Bootstrap類加載器,該類加載器是最為頂層的加載器,其沒有父加載器,它是由C++編寫的,主要負責虛擬機核心類庫的加載-Xbootclasspath來指定根加載器的路徑

擴展類加載器

擴展類加載器的父加載器是根加載器,主要用于加載JAVA_HOME下jre/lb/ext子目錄里面的類庫。由純Java語言實現

系統類加載器

負責加載classpath下的類庫資源

如果大家想了解更多相關知識,可以關注一下動力節點的Java多線程并發編程,里面有更豐富的知識等著大家去學習,希望對大家能夠有所幫助。

提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 久久夜夜视频 | 国产成年女一区二区三区 | 久久99精品久久久久久 | 毛茸茸性毛茸茸大b | 日韩精品一区二区三区 在线观看 | 国产精品麻豆久久99 | 激情都市久久爱 | 热99re国产久热在线 | 奇米影视奇米色777欧美 | 桃花福利视频在线观看 | 4hu四虎免费影院www | 国产黄片毛片 | 奇米成人影视 | 亚洲精品一区最新 | 91九色精品国产免费 | 一级黄色免费毛片 | 操穴网| 欧美激情综合亚洲一二区 | 色综合久久中文 | 久久经典免费视频 | 色综合网亚洲精品久久久 | 一级做受毛片免费大片 | 欧美视频在线一区 | 黄色免费网站在线观看 | 亚洲精品一区91 | 午夜主播国产福利视频在线 | 第一区免费在线观看 | 在线免费一级片 | 2018天天干天天操 | 末成年一级在线看片 | 色片免费观看 | 91在线精品视频 | 国产成人精品男人免费 | 欧美性xxx | 久久久久国产精品免费免费 | 伊人97 | 456性欧美欧美在线视频 | 99在线免费观看 | x8x8国产日韩欧美 | 一区二区三区四区产品乱码伦 | 欧美交换乱理伦片在线观看 |