1. 程式人生 > 其它 >DP_多段 “連續子段和” 的最大值問題

DP_多段 “連續子段和” 的最大值問題

java 建立執行緒池

執行緒池都是通過執行緒池工廠建立,再呼叫執行緒池中的方法獲取執行緒,再通過執行緒去執行任務方法。

Executors:執行緒池建立工廠類
public static ExecutorServicenewFixedThreadPool(int nThreads):返回執行緒池物件
ExecutorService:執行緒池類
Future<?> submit(Runnable task):獲取執行緒池中的某一個執行緒物件,並執行
Future 介面:用來記錄執行緒任務執行完畢後產生的結果。執行緒池建立與使用

這裡介紹兩種使用執行緒池建立執行緒的方法

1):使用Runnable介面建立執行緒池

使用執行緒池中執行緒物件的步驟:

1、建立執行緒池物件
2、建立 Runnable 介面子類物件
3、提交 Runnable 介面子類物件
4、關閉執行緒池

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

class TaskRunnable implements Runnable{
	@Override
	public void run() {
		for (int i = 0; i < 1000; i++) {
			System.out.println("自定義執行緒任務在執行"+i);
		}
	}
}

public class Test {
	public static void main(String[] args) {
	//建立執行緒池物件  引數5,代表有5個執行緒的執行緒池
	ExecutorService service = Executors.newFixedThreadPool(5);
	//建立Runnable執行緒任務物件
	TaskRunnable task = new TaskRunnable();
	//從執行緒池中獲取執行緒物件
	service.submit(task);
	System.out.println("----------------------");
	//再獲取一個執行緒物件
	service.submit(task);
	//關閉執行緒池
	service.shutdown();
	}
}

2)使用Callable介面建立執行緒池

Callable介面:與Runnable介面功能相似,用來指定執行緒的任務。其中的call()方法,用來返回執行緒任務執行完畢後的結果,call方法可丟擲異常。

ExecutorService:執行緒池類

Future submit(Callable task):獲取執行緒池中的某一個執行緒物件,並執行執行緒中的 call() 方法

Future 介面:用來記錄執行緒任務執行完畢後產生的結果。執行緒池建立與使用

使用執行緒池中執行緒物件的步驟:

1、建立執行緒池物件
2、建立 Callable 介面子類物件
3、提交 Callable 介面子類物件
4、關閉執行緒池

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Callable;

class TaskCallable implements Callable<Object>{
	@Override
	public Object call() throws Exception {
		for (int i = 0; i < 1000; i++) {
			System.out.println("自定義執行緒任務在執行"+i);
		}
		return null;
	}
}

public class Test{
	public static void main(String[] args) {
		ExecutorService service = Executors.newFixedThreadPool(3);
		TaskCallable c = new TaskCallable();
		//執行緒池中獲取執行緒物件,呼叫run方法
		service.submit(c);
		//再獲取一個
		service.submit(c);
		//關閉執行緒池
		service.shutdown();
	}
}

用 CompletableFuture 來解決回撥的問題。

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;

public class CompletableFutureDemo {
	public static void main(String[] args) throws InterruptedException {
		long l = System.currentTimeMillis();
		CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
			System.out.println("執行耗時操作...");
			timeConsumingOperation();
			return 100;
		});
		completableFuture.whenComplete((result, e) -> {
			System.out.println("結果:" + result);
		});
		System.out.println("主執行緒運算耗時:" + (System.currentTimeMillis() - l) + " ms");
		new CountDownLatch(1).await();
	}

	static void timeConsumingOperation() {
		try {
			Thread.sleep(3000);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Future 的侷限性

  1. 不能手動完成
    當你寫了一個函式,用於通過一個遠端API獲取一個電子商務產品最新價格。因為這個 API 太耗時,你把它允許在一個獨立的執行緒中,並且從你的函式中返回一個 Future。現在假設這個API服務宕機了,這時你想通過該產品的最新快取價格手工完成這個Future 。你會發現無法這樣做。

  2. Future 的結果在非阻塞的情況下,不能執行更進一步的操作
    Future 不會通知你它已經完成了,它提供了一個阻塞的 get() 方法通知你結果。你無法給 Future 植入一個回撥函式,當 Future 結果可用的時候,用該回調函式自動的呼叫 Future 的結果。
    3.多個 Future 不能串聯在一起組成鏈式呼叫 有時候你需要執行一個長時間執行的計算任務,並且當計算任務完成的時候,你需要把它的計算結果傳送給另外一個長時間執行的計算任務等等。你會發現你無法使用 Future 建立這樣的一個工作流。
    4.不能組合多個 Future 的結果 假設你有10個不同的Future,你想並行的執行,然後在它們執行未完成後執行一些函式。你會發現你也無法使用 Future 這樣做。
    5.沒有異常處理 Future API 沒有任務的異常處理結構居然有如此多的限制,幸好我們有CompletableFuture,你可以使用 CompletableFuture 達到以上所有目的。

CompletableFuture

CompletableFuture 實現了 Future 和 CompletionStage介面,並且提供了許多關於建立,鏈式呼叫和組合多個 Future 的便利方法集,而且有廣泛的異常處理支援。

阿里推薦使用

ExecutorService executor =new ThreadPoolExecutor(........)

Java 8 CompletableFuture 教程

Java 8 CompletableFuture 教程