• vector
    2019-04-21
    最近使用CompletableFuture工具方法以及lamda表达式比较多,语言语法的变化带来编码效率的提升真的很大。
    
     25
  • aroll
    2019-04-20
    建议并发编程课程中的Demo代码,尽量少使用System.out.println, 因为其实现有使用隐式锁,一些情况还会有锁粗化产生

    作者回复: 好建议

     1
     23
  • Asanz
    2019-04-21
    不是不建议使用 Executors 创建线程池了吗???
     1
     13
  • undifined
    2019-04-20
    课后题:
    可以用 Future
            ExecutorService threadPoolExecutor = Executors.newFixedThreadPool(3);
            Future<R> future1 = threadPoolExecutor.submit(Test::getPriceByS1);
            Future<R> future2 = threadPoolExecutor.submit(Test::getPriceByS2);
            Future<R> future3 = threadPoolExecutor.submit(Test::getPriceByS3);
            R r1 = future1.get();
            R r2 = future2.get();
            R r3 = future3.get();

    也可以用 CompletableFuture
            CompletableFuture<R> completableFuture1 = CompletableFuture.supplyAsync(Test::getPriceByS1);
            CompletableFuture<R> completableFuture2 = CompletableFuture.supplyAsync(Test::getPriceByS2);
            CompletableFuture<R> completableFuture3 = CompletableFuture.supplyAsync(Test::getPriceByS3);
            CompletableFuture.allOf(completableFuture1, completableFuture2, completableFuture3)
                             .thenAccept(System.out::println);
     老师这样理解对吗 谢谢老师
    展开
    
     13
  • Joker
    2019-11-06
    ```
    java
    ExecutorService futuresPool = Executors.newFixedThreadPool(3);
            Future<Price> future1 = futuresPool.submit(this::getPriceByS1);
            Future<Price> future2 = futuresPool.submit(this::getPriceByS2);
            Future<Price> future3 = futuresPool.submit(this::getPriceByS3);

            ExecutorService saveThreadPool = Executors.newFixedThreadPool(3);
            saveThreadPool.execute(() -> {
                try {
                    Price r1= future1.get();
                    save(r1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }

            });
            saveThreadPool.execute(() -> {
                try {
                    Price r2= future2.get();
                    save(r2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }

            });
            saveThreadPool.execute(() -> {
                try {
                    Price r3= future3.get();
                    save(r3);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                }
            });
    ```


    用三个线程把这个并行执行,麻烦老师看看,谢谢
    展开

    作者回复: 我觉得没问题。也可以用一个线程池,把查询和保存放一个线程里。

    
     3
  • linqw
    2019-04-22
    课后习题,老师帮忙看下哦
    public class ExecutorExample {
    private static final ExecutorService executor;
        static {executor = new ThreadPoolExecutor(4, 8, 1, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(1000), runnable -> null, (r, executor) -> {//根据业务降级策略});
    }
    static class S1Task implements Callable<String> {
            @Override
            public String call() throws Exception {return getPriceByS1();}}
        static class S2Task implements Callable<String> {
            @Overridepublic String call() throws Exception {return getPriceByS2();}}
        static class S3Task implements Callable<String> {@Override public String call() throws Exception {return getPriceByS3();}}
        static class SaveTask implements Callable<Boolean> {private List<FutureTask<String>> futureTasks; public SaveTask(List<FutureTask<String>> futureTasks) {this.futureTasks = futureTasks;
    }
            @Override
            public Boolean call() throws Exception {
                for (FutureTask<String> futureTask : futureTasks) {
                    String data = futureTask.get(10, TimeUnit.SECONDS);
                    saveData(data);
                }
                return Boolean.TRUE;
            }
        }
        private static String getPriceByS1() {
            return "fromDb1";
        }
        private static String getPriceByS2() {
            return "fromDb2";
        }
        private static String getPriceByS3() {
            return "fromDb3";
        }
        private static void saveData(String data) {
            //save data to db
        }
        public static void main(String[] args) {
            S1Task s1Task = new S1Task();FutureTask<String> st1 = new FutureTask<>(s1Task);S2Task s2Task = new S2Task();FutureTask<String> st2 = new FutureTask<>(s2Task);S3Task s3Task = new S3Task();FutureTask<String> st3 = new FutureTask<>(s3Task);List<FutureTask<String>> futureTasks = Lists.<FutureTask<String>>newArrayList(st1, st2, st3);FutureTask<Boolean> saveTask = new FutureTask<>(new SaveTask(futureTasks));executor.submit(st1);executor.submit(st2);executor.submit(st3);executor.submit(saveTask);}}
    展开

    作者回复: 没问题,就是有点复杂,代码还可以精简一下

     1
     3
  • 三木禾
    2019-05-18
    这个可以用生产消费者模式啊
    
     2
  • 💪😊
    2019-04-30
    分别提交三个futuretask给线程池,然后最后分别get出结果,统一进行保存数据库
    
     2
  • 圆圜
    2019-04-22
    你这个不对啊,应该是executeservice.submit t2furturetask,不能直接提交t2
    
     2
  • QQ怪
    2019-04-20
    在实际项目中应用已经应用到了Feture,但没有使用线程池,没有那么优雅,所以算是get到了👍
    
     2
  • 张三
    2019-04-20
    打卡。感觉很神奇,之前完全不会用。学的知识太陈旧了,继续学习。
    
     2
  • henry
    2019-04-20
    现在是在主线程串行完成3个询价的任务,执行第一个任务,其它2个任务只能等待执行,如果要提高效率,这个地方需要改进,可以用老师今天讲的futuretask,三个询价任务改成futuretask并行执行,效率会提高

    作者回复: 👍

    
     2
  • 张天屹
    2019-04-20
    我不知道是不是理解错老师意思了,先分析依赖有向图,可以看到三条线,没有入度>1的节点
    那么启动三个线程即可。
    图:
    s1询价 -> s1保存
    s2询价 -> s2保存
    s3询价 -> s3保存
    代码:
            new Thread(() -> {
                r1 = getPriceByS1();
                save(r1);
            }).start();
            new Thread(() -> {
                r2 = getPriceByS2();
                save(r2);
            }).start();
            new Thread(() -> {
                r3 = getPriceByS3();
                save(r3);
            }).start();
    我觉得这里不需要future,除非询价和保存之间还有别的计算工作
    展开

    作者回复: 用线程池就用到了

     2
     2
  • 稚者
    2019-11-01
    烧水泡茶的Demo有点小问题,Task2的启动时间应该在Task1的洗茶壶之后开始,现在的代码是一起开始。
    
     1
  • 魏斌斌
    2019-06-17
    老师,我看了下futruerask的源码,当调用futrue.get()方法,其实最终会调用unsafe方法是当前线程阻塞。但是我不太理解线程阻塞到哪去了,也没看到锁。

    作者回复: 可以看看操作系统原理有关线程,进程的那部分

    
     1
  • Sunqc
    2019-04-30
    老师,你所说的订蛋糕,我这样理解对吗,把任务提交给线程池就是让蛋糕店做蛋糕;去看电影就是主线程做其他事,提货单是对应调用future的get

    作者回复: 理解的对

    
     1
  • liu
    2019-04-25
    future是阻塞的等待。发起任务后,做其他的工作。做完后,从future获取处理结果,继续进行后面的任务
    
     1
  • 捞鱼的搬砖奇
    2019-04-21
    Future的get()是拿到任务的执行结果不吧。为什么又说是拿到方法的入参了。
    
     1
  • QQ怪
    2019-04-20
    老师,在提交 Runnable 任务及结果引用的例子里面的x变量是什么?

    作者回复: 任意的东西,想成数字0也行

    
     1
  • 是我!
    2019-11-30
    老师您好:请问这样是否有问题?
    public static void main(String[] args) throws Exception {
            FutureTask t1 = new FutureTask(new Callable() {
                @Override
                public String call() {
                    return "getPriceByS1()";
                }
            });
            FutureTask t2 = new FutureTask(() -> "getPriceByS2()");
            FutureTask t3 = new FutureTask(() -> "getPriceByS3()");
            BlockingQueue<Runnable> blockingQueue = new ArrayBlockingQueue<>(3);
            ThreadPoolExecutor poolExecutor =
                    new ThreadPoolExecutor(10, 10, 10,
                            TimeUnit.SECONDS, blockingQueue);
            poolExecutor.submit(t1);
            save(t1.get().toString());
            poolExecutor.submit(t2);
            save(t2.get().toString());
            poolExecutor.submit(t3);
            save(t3.get().toString());
        }

        private static void save(String ss) {
            System.out.println("保存" + ss);
        }
    展开

    作者回复: 我觉得有问题,save慢会影响了submit

    
    
我们在线,来聊聊吧