大战熟女丰满人妻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多線程并發編程,里面有更豐富的知識等著大家去學習,希望對大家能夠有所幫助。

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

免費課程推薦 >>
技術文檔推薦 >>
主站蜘蛛池模板: 久久成人永久免费播放 | aa大片成人免费网站 | 亚洲欧美精品中字久久99 | 亚洲这里只有精品 | 日日爽视频 | 亚洲综合图片小说区热久久 | 国产国产精品人在线观看 | 久草首页在线观看 | 精品国产调教最大网站女王 | 国产精品高清在线观看 | 免费小视频 | 日本精品久久久久中文字幕 1 | 啪啪网站色大全免费 | 亚洲图片欧美视频 | 色中色综合 | 欧美一欧美一区二三区性 | 亚洲免费精品 | 国产日韩视频 | 色偷偷要色偷偷网站视频在线 | 97精品久久天干天天蜜 | 天天拍天天干 | 狠狠躁日日躁人人爽 | 黄色自拍网站 | 久久精品视频日本 | 欧美成人久久 | 亚洲爱爱视频 | 在线观看亚洲免费 | 色网站欧美 | 国产亚洲精品久久午夜 | 男女啪网站 | 九九九九九九精品免费 | 日本高清一道本 | 久久中文字幕一区二区三区 | 欧美日韩亚洲精品一区 | 国产精品福利在线观看入口 | 色片在线免费观看 | 国产日本亚洲 | 国产高清一区 | 亚洲 欧美 国产另类首页 | 日日天天干 | 羞羞视频网页 |