1. 程式人生 > >多執行緒學習-day-01

多執行緒學習-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