V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
woxiangjingjing
V2EX  ›  Java

多线程问题

  •  
  •   woxiangjingjing · 2019-08-06 10:44:25 +08:00 · 4181 次点击
    这是一个创建于 1961 天前的主题,其中的信息可能已经有所发展或是发生改变。

    多线程情况下,根据业务唯一业务 id 查询 a,b,c 三个表,并且将三个表数据集成起来怎么显示

    15 条回复    2019-08-16 09:44:13 +08:00
    1424659514
        1
    1424659514  
       2019-08-06 13:38:49 +08:00
    emmmmmm, 只是查询的话跟多线程没太大关系呀
    snappyone
        2
    snappyone  
       2019-08-06 13:41:08 +08:00
    Countdownlatch 并发查询,然后代码里面合并数据
    dovme
        3
    dovme  
       2019-08-06 14:33:16 +08:00
    @snappyone #2 +1
    zardly666
        4
    zardly666  
       2019-08-06 14:36:28 +08:00
    线程用 Callable+Future 返回数据,三个线程都返回值以后在 Countdownlatch 倒计时完毕后 把数据合并起来
    hunterzhang86
        5
    hunterzhang86  
       2019-08-06 15:06:24 +08:00
    我一般用 LinsteningExecutorService 和 CountDownLatch 结合起来做,在 onSuccess 和 onFailure 里面使用 countDown()方法,这样便于捕获到异常情况。
    woxiangjingjing
        6
    woxiangjingjing  
    OP
       2019-08-06 16:18:00 +08:00
    @zardly666 countdownlatch 是在哪用啊,这种写对不对
    public class test {



    public static void main(String[] args) {
    ExecutorService executor = Executors.newCachedThreadPool();
    A a = new A();
    B b = new B();
    C c = new C();

    Future<Integer> result = executor.submit(a);
    Future<Integer> result1 = executor.submit(b);
    Future<Integer> result2 = executor.submit(c);
    executor.shutdown();

    try {
    Thread.sleep(1000);
    } catch (InterruptedException e1) {
    e1.printStackTrace();
    }

    System.out.println("主线程在执行任务");

    try {
    System.out.println("task 运行结果"+result.get()+result1.get()+result2.get());
    } catch (InterruptedException e) {
    e.printStackTrace();
    } catch (ExecutionException e) {
    e.printStackTrace();
    }

    System.out.println("所有任务执行完毕");
    }
    }

    class A implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
    System.out.println("查询 A 表数据");
    Thread.sleep(3000);
    int sum = 0;
    for(int i=0;i<100;i++)
    sum += i;
    return sum;
    }
    }
    class B implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
    System.out.println("查询 B 表数据");
    Thread.sleep(3000);
    int sum = 0;
    for(int i=0;i<100;i++)
    sum += i;
    return sum;
    }
    }
    class C implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
    System.out.println("查询 C 表数据");
    Thread.sleep(3000);
    int sum = 0;
    for(int i=0;i<100;i++)
    sum += i;
    return sum;
    }
    }
    lihongjie0209
        7
    lihongjie0209  
       2019-08-06 16:23:30 +08:00
    前端的 promise java 中的 completeableFuture
    zardly666
        8
    zardly666  
       2019-08-06 16:33:58 +08:00
    @woxiangjingjing CountDownLatch 是一个类,要传参数


    import java.util.concurrent.*;
    public class Count {
    public static void main(String[] args) {
    ExecutorService executor = Executors.newCachedThreadPool();
    //定时器要传参数(几个线程完成以后再执行主线程)
    CountDownLatch latch = new CountDownLatch(3);
    //每个线程要把 CountDownLatch 传进去,每个线程完成以后倒计时-1
    A a = new A(latch);
    B b = new B(latch);
    C c = new C(latch);

    Future<Integer> result = executor.submit(a);
    Future<Integer> result1 = executor.submit(b);
    Future<Integer> result2 = executor.submit(c);

    executor.shutdown();
    //3 个线程都完成以后就会执行主线程
    try {
    Thread.sleep(1000);
    } catch (InterruptedException e1) {
    e1.printStackTrace();
    }

    System.out.println("主线程在执行任务");

    try {
    System.out.println("task 运行结果"+result.get()+result1.get()+result2.get());
    } catch (InterruptedException e) {
    e.printStackTrace();
    } catch (ExecutionException e) {
    e.printStackTrace();
    }
    System.out.println("所有任务执行完毕");

    }
    }

    import java.util.concurrent.Callable;
    import java.util.concurrent.CountDownLatch;

    public class A implements Callable<Integer>{
    CountDownLatch latch;
    public A(CountDownLatch latch) {
    this.latch = latch;
    }

    @Override
    public Integer call() throws Exception {
    System.out.println("查询 A 表数据");
    Thread.sleep(3000);
    int sum = 0;
    for(int i=0;i<100;i++)
    sum += i;
    latch.countDown();
    return sum;
    }
    }

    你的 CountDownLatch 用的不对,再看看相关知识吧~
    zardly666
        9
    zardly666  
       2019-08-06 16:40:46 +08:00
    还有求和 相加运算括起来,不然输出的是字符串相加了就成 495049504950 了
    System.out.println("task 运行结果"+(result.get()+result1.get()+result2.get()));


    latch.countDown();
    每个线程中的倒计时减少是这个
    l8g
        10
    l8g  
       2019-08-06 17:07:46 +08:00   ❤️ 1
    @zardly666 你这用的也不对吧

    另外楼主这个场景直接用 Future 就行了,没有再使用 CountDownLatch 的必要吧。
    zardly666
        11
    zardly666  
       2019-08-06 17:13:55 +08:00   ❤️ 1
    @l8g 哈哈是的 我打上去也发现了- - 没必要 CountDownLatch 直接 Future 就完事辽=、= 我看楼上说了个 CountDownLatch 想偏了
    zardly666
        12
    zardly666  
       2019-08-06 17:18:05 +08:00
    @woxiangjingjing 帮我删一下我的回复=。= 谢谢~ 我那个不对,直接多线程 Future 带回来处理就行了
    woxiangjingjing
        13
    woxiangjingjing  
    OP
       2019-08-06 20:35:58 +08:00
    @zardly666 @l8g 假如相关联的书籍达到几十万条的时候,合并的时候怎么合并,是有 jdk8 的 stream 和 lamada 吗,还有没有别的解决方案没
    aguesuka
        14
    aguesuka  
       2019-08-07 09:16:30 +08:00 via Android
    用 fork/join
    anakinsky
        15
    anakinsky  
       2019-08-16 09:44:13 +08:00
    CompletableFuture.supplyAsync,然后 join 聚合
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3301 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 00:39 · PVG 08:39 · LAX 16:39 · JFK 19:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.