3 changed files with 237 additions and 3 deletions
-
2tp-admin/src/main/java/com/inscloudtech/web/controller/system/TestReportController.java
-
4tp-admin/src/main/resources/application.yml
-
234tp-functional/src/main/java/com/inscloudtech/functional/controller/demo/BestParallelController.java
@ -0,0 +1,234 @@ |
|||||
|
package com.inscloudtech.functional.controller.demo; |
||||
|
|
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.springframework.web.bind.annotation.RequestMapping; |
||||
|
import org.springframework.web.bind.annotation.RestController; |
||||
|
|
||||
|
import java.text.DecimalFormat; |
||||
|
import java.text.DecimalFormatSymbols; |
||||
|
import java.util.ArrayList; |
||||
|
import java.util.List; |
||||
|
import java.util.Locale; |
||||
|
import java.util.Random; |
||||
|
import java.util.concurrent.CompletableFuture; |
||||
|
import java.util.concurrent.Executor; |
||||
|
import java.util.concurrent.Executors; |
||||
|
import java.util.stream.Collectors; |
||||
|
|
||||
|
/** |
||||
|
* Java 最强并行(I/O密集型)方法 |
||||
|
* @author aoe |
||||
|
* @date 2021/2/20 |
||||
|
*/ |
||||
|
|
||||
|
@Slf4j |
||||
|
@RestController |
||||
|
@RequestMapping("/demo/bestParallel") |
||||
|
public class BestParallelController { |
||||
|
|
||||
|
private final List<Shop> shops = getShops(100); |
||||
|
|
||||
|
private final Executor executor = |
||||
|
Executors.newFixedThreadPool(Math.min(shops.size(), 100), r -> { |
||||
|
Thread t = new Thread(r); |
||||
|
t.setDaemon(true); |
||||
|
return t; |
||||
|
}); |
||||
|
|
||||
|
public static void main(String[] args) { |
||||
|
BestParallelController test = new BestParallelController(); |
||||
|
|
||||
|
// 创建一个线程来执行CPU密集型任务 |
||||
|
Thread cpuIntensiveThread = new Thread(() -> { |
||||
|
long startTime = System.nanoTime(); |
||||
|
|
||||
|
// 模拟CPU密集型操作 |
||||
|
for (int i = 0; i < 1_000_000_000; i++) { |
||||
|
// 进行一些计算 |
||||
|
long sum = 0; |
||||
|
for (int j = 0; j < 1_000_000_000; j++) { |
||||
|
sum += j; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
long endTime = System.nanoTime(); |
||||
|
long duration = (endTime - startTime) / 1_000_000; // 转换为毫秒 |
||||
|
|
||||
|
System.out.println("CPU密集型任务完成,耗时:" + duration + "毫秒"); |
||||
|
}); |
||||
|
|
||||
|
// 启动线程 |
||||
|
cpuIntensiveThread.start(); |
||||
|
|
||||
|
long start = System.nanoTime(); |
||||
|
test.findPrices("car"); |
||||
|
long duration = (System.nanoTime() - start) / 1_000_000; |
||||
|
System.out.println("普通版 done in " + duration + " msecs"); |
||||
|
// 15115 |
||||
|
|
||||
|
start = System.nanoTime(); |
||||
|
test.findPricesBest("car"); |
||||
|
duration = (System.nanoTime() - start) / 1_000_000; |
||||
|
System.out.println("最强版 done in " + duration + " msecs"); |
||||
|
// 1020 |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
} |
||||
|
|
||||
|
public List<String> findPrices(String product) { |
||||
|
List<CompletableFuture<String>> priceFutures = |
||||
|
shops.stream() |
||||
|
// 使用 CompletableFuture 以异步方式及时每种商品的价格 |
||||
|
.map(shop -> CompletableFuture.supplyAsync(() -> shop.getName() + " price is" + shop.getPrice(product)) |
||||
|
) |
||||
|
.collect(Collectors.toList()); |
||||
|
return priceFutures.stream() |
||||
|
// 等待所有异步操作结束 |
||||
|
.map(CompletableFuture::join) |
||||
|
.collect(Collectors.toList()); |
||||
|
} |
||||
|
|
||||
|
public List<String> findPricesBest(String product) { |
||||
|
List<CompletableFuture<String>> priceFutures = |
||||
|
shops.stream() |
||||
|
// 使用 CompletableFuture 以异步方式及时每种商品的价格 |
||||
|
.map(shop -> CompletableFuture.supplyAsync(() -> shop.getName() + " price is" + shop.getPrice(product), executor) |
||||
|
) |
||||
|
.collect(Collectors.toList()); |
||||
|
return priceFutures.stream() |
||||
|
// 等待所有异步操作结束 |
||||
|
.map(CompletableFuture::join) |
||||
|
.collect(Collectors.toList()); |
||||
|
} |
||||
|
|
||||
|
private List<Shop> getShops(int count) { |
||||
|
List<Shop> list = new ArrayList<>(count); |
||||
|
for (int i = 0; i < count; i++) { |
||||
|
list.add(new Shop("Shop" + i)); |
||||
|
} |
||||
|
return list; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class Shop { |
||||
|
|
||||
|
private final String name; |
||||
|
private final Random random; |
||||
|
|
||||
|
public Shop(String name) { |
||||
|
this.name = name; |
||||
|
random = new Random(name.charAt(0) * name.charAt(1) * name.charAt(2)); |
||||
|
} |
||||
|
|
||||
|
public String getPrice(String product) { |
||||
|
double price = calculatePrice(product); |
||||
|
Discount.Code code = Discount.Code.values()[random.nextInt(Discount.Code.values().length)]; |
||||
|
return name + ":" + price + ":" + code; |
||||
|
} |
||||
|
|
||||
|
public double calculatePrice(String product) { |
||||
|
Util.delay(); |
||||
|
return Util.format(random.nextDouble() * product.charAt(0) + product.charAt(1)); |
||||
|
} |
||||
|
|
||||
|
public String getName() { |
||||
|
return name; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
class Discount { |
||||
|
|
||||
|
public enum Code { |
||||
|
NONE(0), SILVER(5), GOLD(10), PLATINUM(15), DIAMOND(20); |
||||
|
|
||||
|
private final int percentage; |
||||
|
|
||||
|
Code(int percentage) { |
||||
|
this.percentage = percentage; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static String applyDiscount(Quote quote) { |
||||
|
return quote.getShopName() + " price is " + Discount.apply(quote.getPrice(), quote.getDiscountCode()); |
||||
|
} |
||||
|
|
||||
|
private static double apply(double price, Code code) { |
||||
|
Util.delay(); |
||||
|
return Util.format(price * (100 - code.percentage) / 100); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
class Util { |
||||
|
|
||||
|
private static final Random RANDOM = new Random(0); |
||||
|
private static final DecimalFormat formatter = new DecimalFormat("#.##", new DecimalFormatSymbols(Locale.US)); |
||||
|
|
||||
|
public static void delay() { |
||||
|
int delay = 1000; |
||||
|
//int delay = 500 + RANDOM.nextInt(2000); |
||||
|
try { |
||||
|
Thread.sleep(delay); |
||||
|
} catch (InterruptedException e) { |
||||
|
throw new RuntimeException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static double format(double number) { |
||||
|
synchronized (formatter) { |
||||
|
return new Double(formatter.format(number)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static <T> CompletableFuture<List<T>> sequence(List<CompletableFuture<T>> futures) { |
||||
|
/* |
||||
|
CompletableFuture<Void> allDoneFuture = |
||||
|
CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])); |
||||
|
return allDoneFuture.thenApply(v -> |
||||
|
futures.stream() |
||||
|
.map(future -> future.join()) |
||||
|
.collect(Collectors.<T>toList()) |
||||
|
); |
||||
|
*/ |
||||
|
return CompletableFuture.supplyAsync(() -> futures.stream() |
||||
|
.map(future -> future.join()) |
||||
|
.collect(Collectors.<T>toList())); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
class Quote { |
||||
|
|
||||
|
private final String shopName; |
||||
|
private final double price; |
||||
|
private final Discount.Code discountCode; |
||||
|
|
||||
|
public Quote(String shopName, double price, Discount.Code discountCode) { |
||||
|
this.shopName = shopName; |
||||
|
this.price = price; |
||||
|
this.discountCode = discountCode; |
||||
|
} |
||||
|
|
||||
|
public static Quote parse(String s) { |
||||
|
String[] split = s.split(":"); |
||||
|
String shopName = split[0]; |
||||
|
double price = Double.parseDouble(split[1]); |
||||
|
Discount.Code discountCode = Discount.Code.valueOf(split[2]); |
||||
|
return new Quote(shopName, price, discountCode); |
||||
|
} |
||||
|
|
||||
|
public String getShopName() { |
||||
|
return shopName; |
||||
|
} |
||||
|
|
||||
|
public double getPrice() { |
||||
|
return price; |
||||
|
} |
||||
|
|
||||
|
public Discount.Code getDiscountCode() { |
||||
|
return discountCode; |
||||
|
} |
||||
|
|
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue