Java并发编程 | 第五篇:Java并行模式之并行流水线

假如现在有两个数,B和C。如果要计算(B+C)*B/2,那么这个运算过程就是无法并行的。原因是,如果B+C没有执行完成,则永远算不出(B+C)*B,这就是数据相关性。
可以借鉴日常生产中的流水线思想,首先将计算过程拆分为三个步骤:
P1:A=B+C
P2:D=AxB
P3:D=D/2
上述步骤中P1、P2和P3均在单独的线程中计算,并且每个线程只负责自己的工作。此时,P3的计算结果就是最终需要的答案。


简单实现

载体

为了实现这个功能,我们需要定义一个在线程间携带结果进行信息交换的载体

public class Msg {
  public double i;
  public double j;
  public String orgStr=null;
}

P1计算的加法

public class Plus implements Runnable{

    public static BlockingQueue<Msg> bg=new LinkedBlockingQueue<Msg>();
    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            try {
                Msg msg=bg.take();
                msg.j=msg.i+msg.j;
                Multiply.bg.add(msg);
            } catch (Exception e) {

            }
        }
    }
}

可以看出,P1从共享管道BlockingQueue取出Msg,然后使用Msg封装的i和j进行求和操作,然后通过把结果添加到P2的共享管道BlockingQueue,传递给P2

P2计算的乘法

public class Multiply implements Runnable {
    public static BlockingQueue<Msg> bg=new LinkedBlockingQueue<Msg>();
    @Override
    public void run() {
        while(true){
            try {
                Msg msg=bg.take();
                msg.i=msg.i*msg.j;
                Div.bg.add(msg);
            } catch (Exception e) {
                // TODO: handle exception
            }
        }

    }

}

P3计算的除法

public class Div implements Runnable {
    public static BlockingQueue<Msg> bg = new LinkedBlockingQueue<Msg>();

    @Override
    public void run() {
        while (true) {
        try {
          Msg msg=bg.take();
          msg.i=msg.i/2;
          System.out.println(msg.orgStr+"="+msg.i);
            } catch (Exception e) {
          }
        }
    }
}

这个可以得到最终结果,所以我们就输出最终结果,msg.orgStr是计算格式的字符串

测试

public class PStreamMain {
     public static void main(String[] args) {
        new Thread(new Plus()).start();
        new Thread(new Multiply()).start();
        new Thread(new Div()).start();

        for(int i=0;i<=1000;i++){
            for(int j=0;j<=1000;j++){
                Msg msg=new Msg();
                msg.i=i;
                msg.j=j;
                msg.orgStr="(("+i+"+"+j+")*"+i+")/2";
                Plus.bg.add(msg);
            }

        }
    }
}

这里写图片描述


总结

你会发现并发流水线是通过BlockingQueue这个共享管道,通过依赖关系串联起来,把操作分配在不同线程中进行计算,尽可能利用多核优势

参考:《Java高并发程序设计》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值