【面試系列5】JUC

並行與併發

並行:多個機器同時執行
併發:一個機器分時執行

Future接口

定義了操作異步任務執行的一些方法,獲取異步任務執行的結果,取消任務的執行,判斷任務是否被取消,判斷任務執行完畢。
多線程/有返回/異步任務

class MyThread2 implements Callable<String>{

    @Override
    public String call() throws Exception {
        System.out.println("execute");
        return "hello";
    }
}

public class aa {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        FutureTask futureTask=new FutureTask(new MyThread2());
        System.out.println(futureTask.isDone());
        futureTask.run();
        System.out.println(futureTask.isDone());
        System.out.println(futureTask.get());

    }
}

使用線程池


public class FutureThreadPool {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService threadPool = Executors.newFixedThreadPool(3);

        Long startTime=System.currentTimeMillis();
        FutureTask<String> futureTask1 = new FutureTask<>(() -> {
            try {
                TimeUnit.MILLISECONDS.sleep(500);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "futureTask1 success";
        });
        threadPool.submit(futureTask1);
        FutureTask<String> futureTask2 = new FutureTask<>(() -> {
            try {
                TimeUnit.MILLISECONDS.sleep(300);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "futureTask1 success";
        });
        threadPool.submit(futureTask2);
        try {
            TimeUnit.MILLISECONDS.sleep(300);
        } catch (Exception e) {
            e.printStackTrace();
        }
        futureTask1.get();
        futureTask2.get();
        Long endTime=System.currentTimeMillis();
        System.out.println(endTime-startTime);
        threadPool.shutdown();

    }
}

問題:

  1. 假如果get放在主線程前面,會阻塞主線程。
    get(long time,TimeUnit unit)
    超時便拋出異常

  2. 輪詢會導致CPU空轉。
    while(!futureTask.isDone()){
    }
    futureTask1.get();

注意:回調通知,便不需要輪詢。

使用CompletableFuture,異步回調。

public class CompletableFutureTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService threadPool = Executors.newFixedThreadPool(3);
        CompletableFuture completableFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println(Thread.currentThread().getName());
            return "hello";
        }, threadPool);
        System.out.println(completableFuture.get());
    }
}
public class CompletableFutureTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ExecutorService threadPool = Executors.newFixedThreadPool(3);

        CompletableFuture<String> step1 = CompletableFuture.supplyAsync(() -> {
            System.out.println("step1 come in");
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("step1 run end");
            return "step1";
        },threadPool).whenComplete((v, e) -> {
            if (e == null) {
                System.out.println("步驟1 結束");
                step2();
            }
        }).exceptionally(e -> {
            e.printStackTrace();
            return null;
        });
        System.out.println("主線程");



    }

    private static void step2() {
        CompletableFuture<String> comeIn = CompletableFuture.supplyAsync(() -> {
            System.out.println("step2 come in");
            try {
                sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println("step2 run end");
            return "step2";
        });
        try {
            System.out.println(comeIn.get());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } catch (ExecutionException e) {
            throw new RuntimeException(e);
        }
    }
}

電商比價需求:

public class MallTest {

    static List<NetMall> list = Arrays.asList(new NetMall("jd"), new NetMall("dd"), new NetMall("tb"));

    //public static List<String> getPrice(List<NetMall> list, String product) {
    //    return list.stream().map(netMall -> product + " in " + netMall.getNetMall() + " " + netMall.getPrice(product)).collect(Collectors.toList());
    //}
    public static List<String> getPrice(List<NetMall> list, String product) {
        return list.stream()
                .map(netMall -> CompletableFuture.supplyAsync(() -> product + " in " + netMall.getNetMall() + " " + netMall.calPrice(product)))
                .collect(Collectors.toList())
                .stream()
                .map(t->t.join())
                .collect(Collectors.toList());
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        long startTime = System.currentTimeMillis();
        List<String> list1 = getPrice(list, "mysql");
        for (String s : list1) {
            System.out.println(s);
        }

        long endTime = System.currentTimeMillis();
        System.out.println("執行時間:" + (endTime - startTime));
    }
}

@Data
@AllArgsConstructor
class NetMall {
    private String netMall;

    public BigDecimal calPrice(String productName) {
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        return BigDecimal.valueOf(ThreadLocalRandom.current().nextDouble() * 2 + productName.charAt(0));
    }
}

https://blog.csdn.net/dolpin_ink/article/details/125116590

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章