多執行緒學習-day-01
執行緒基礎、執行緒之間的共享和協作
(目前會將一些概念簡單描述,一些重點的點會詳細描述)
1,CPU核心數和執行緒數之間的關係
①、一塊CPU只有一塊處理器
②、Inter提出了多核處理器
③、CPU核心數 和 執行緒數 是 1:1 的關係
④、Inter提出了超執行緒,CPU核心數 和 執行緒數 是 1:2 的關係
⑤、CPU同一時間只能執行16個執行緒
2、CPU時間片輪轉機制
①、RR排程:首先將所有就緒的佇列按FCFS策略排成一個就緒佇列,然後系統設定一定的時間片,每次給隊首作業分配時間片。如果此作業執行結束,即使時間片沒用完,立刻從佇列中去除此作業,並給下一個作業分配新的時間片;如果作業時間片用完沒有執行結束,則將此作業重新加入就緒佇列尾部等待排程。
②、CPU時間片輪轉機制可能會導致上下文切換。
3、什麼是程序和執行緒?
①、程序是程式執行資源分配的最小單位。程序內部有多個執行緒,會共享這個程序中的資源。
②、執行緒是CPU排程的最小單位。必須依賴程序而存在。
4、並行和併發的區別?
①、並行:同一時刻,可同時處理問題的能力。比如售票視窗多開,多開的視窗表示同時處理的能力。
②、併發:與單位時間相關,在單位時間內處理事情的能力。
5、高併發程式設計的意義、好處和注意事項
①好處:充分利用CPU資源,加快使用者響應時間,程式模組化,非同步化。
②問題:A、執行緒共享資源,存在衝突;B、容易導致死鎖;C、啟用太多執行緒,可能會搞垮機器。
6、學習多執行緒
①、Java裡的程式天生就是多執行緒的。
A、ThreadMXBean是Java虛擬機器為我們提供執行緒管理的介面,通過該類可以拿到應用中有多少個執行緒。
B、至少會執行5個執行緒:
1、main主函式執行緒 2、Reference Handler負責清除引用的執行緒 3、Finalizer呼叫物件的Final方法的執行緒 4、Signal Dispatcher分發,處理髮送給虛擬機器訊號的執行緒 5、Attach Listener獲取當前程式執行相關資訊
import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
public class OnlyMain {
public static void main(String[] args) {
// Java虛擬機器 為我們提供的執行緒裡面,執行緒管理的介面,通過該類可以拿到應用程式裡面有多少個執行緒
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
// 是否看鎖,這裡不看鎖,一般用不到,返回值是ThreadInfo的陣列
ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
// 遍歷陣列
for (ThreadInfo threadInfo : threadInfos) {
/**
* main主函式執行緒
* Reference Handler負責清除引用的執行緒
* Finalizer呼叫物件的Final方法的執行緒
* Signal Dispatcher分發,處理髮送給虛擬機器訊號的執行緒
* Attach Listener獲取當前程式執行相關資訊
*/
System.out.println("【" + threadInfo.getThreadId() + "】 " + threadInfo.getThreadName());
}
}
}
控制檯輸出:
【5】 Attach Listener
【4】 Signal Dispatcher
【3】 Finalizer
【2】 Reference Handler
【1】 main
C、實現多執行緒的三種方式及區別:
1、繼承Thread類
2、實現Runnable介面
3、實現Callable介面,允許有返回值,並且不能直接用new Thread來啟動該多執行緒介面物件,而是需要先用FutureTask物件來轉換一次,再呼叫new Thread()來啟動Callable多執行緒物件
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class NewThread {
/* 擴充套件自Thread類 */
/* 實現Runnable介面 */
private static class UseRunnable implements Runnable {
@Override
public void run() {
System.out.println("It is a Runnable!");
}
}
/* 實現Callable介面,允許有返回值 */
private static class UseCallable implements Callable<String> {
@Override
public String call() throws Exception {
System.out.println("It is a Callable!");
return "CallableResult";
}
}
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 例項化Runnable介面物件
UseRunnable useRunnable = new UseRunnable();
// 通過new Thread來執行Runnable多執行緒物件
new Thread(useRunnable).start();
// 例項化Callable介面物件
UseCallable useCallble = new UseCallable();
// Thread不能夠執行Callable介面物件,只能通過FutureTask介面轉換後在執行
FutureTask<String> futureTask = new FutureTask<>(useCallble);
new Thread(futureTask).start();
System.out.println(futureTask.get());
}
}
控制檯輸出:
It is a Runnable!
It is a Callable!
CallableResult