記錄學習內容。看網路上大大們的文章和影片,做些紀錄。
把這邊當作寫筆記的地方,內容可能有錯誤。
教學來源:
Java Concurrency Interview: Implement Scatter Gather pattern
情況:同時3個http執行緒執行,然後忽略3秒內沒完成http request的執行緒。
影片裡教了三種方法:
第一種方式 : threadPool和 thread.sleep
第二種方式 : CountDownLatch 和 latch.await
第三種方式 : CompletableFuture.runAsync
程式來自影片:
像是現在有3個http request 要去爬蟲 ,3秒內沒爬到的就不理。
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.*;
public class ThreadTest9 {
static ExecutorService threadPool = Executors.newFixedThreadPool(4);
//CountDownLatch 和 threadPool.submit
private static Set<Integer> getPrices(int productId) throws InterruptedException {
Set<Integer> prices = Collections.synchronizedSet(new HashSet<>());
CountDownLatch latch = new CountDownLatch(3);
threadPool.submit(new Task("google", productId, prices, latch));
threadPool.submit(new Task("fb", productId, prices, latch));
threadPool.submit(new Task("twitter", productId, prices, latch));
// Thread.sleep(3*1000);
// latch.await();
latch.await(3, TimeUnit.SECONDS); //3 seconds 或是 CountDownLatch變成0
System.out.println("finished getPrices" + prices);
return prices;
}
//CompletableFuture
private static Set<Integer> getPrices1(int productId) throws InterruptedException, TimeoutException, ExecutionException {
Set<Integer> prices = Collections.synchronizedSet(new HashSet<>());
CompletableFuture<Void> task1 = CompletableFuture.runAsync(new Task("google", productId, prices));
CompletableFuture<Void> task2 = CompletableFuture.runAsync(new Task("fb", productId, prices));
CompletableFuture<Void> task3 = CompletableFuture.runAsync(new Task("twitter", productId, prices));
CompletableFuture<Void> allTasks = CompletableFuture.allOf(task1, task2, task3);
allTasks.get(3, TimeUnit.SECONDS);
System.out.println("finished getPrices1" + prices);
return prices;
}
//執行緒
private static class Task implements Runnable {
private String url;
private int productId;
private Set<Integer> prices;
private CountDownLatch latch;
public Task(String url, int productId, Set<Integer> prices, CountDownLatch latch) {
this.url = url;
this.productId = productId;
this.prices = prices;
this.latch = latch;
}
public Task(String url, int productId, Set<Integer> prices) {
this.url = url;
this.productId = productId;
this.prices = prices;
//this.latch = latch;
}
@Override
public void run() {
int price = (int) (Math.random() * 100) + 1;
prices.add(price);
try {
//Thread.sleep(2000); // 沒有timeout
Thread.sleep(4000); // 有timeout
} catch (InterruptedException e) {
e.printStackTrace();
}
// System.out.println("prices:" + prices);
if (latch != null)
latch.countDown();
}
}
public static void main(String args[]) throws TimeoutException, ExecutionException {
try {
getPrices(5);
getPrices1(5);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
結果(時間內沒完成):
finished getPrices[55, 75, 45]
Exception in thread "main" java.util.concurrent.TimeoutException
at java.util.concurrent.CompletableFuture.timedGet(CompletableFuture.java:1771)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1915)
at ThreadTest9.getPrices1(ThreadTest9.java:39)
at ThreadTest9.main(ThreadTest9.java:87)
結果(時間內完成):
finished getPrices[64, 4, 9]
finished getPrices1[7, 59, 95]