写一个简单的工作流(三)

上午测试了下并发情况下的表现,测试场景:一个有20个节点,包括选择、顺序、并行路由的流程,所有节点都设置为自动执行,1000个线程并发启动案例,也就是这个流程同时有1000个案例在跑,全部跑完结果差强人意,比单线程慢了接近30倍。仔细调整了算法和加锁粒度,尽管整体性能有所提高,但是多线程和单线程间执行的差距仍然没有多大变化,性能瓶颈还是在核心的调度算法上,还需要分析下。测试程序如下:

package net.rubyeye.insect.workflow.test;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CyclicBarrier;

import net.rubyeye.insect.workflow.Place;
import net.rubyeye.insect.workflow.Token;
import net.rubyeye.insect.workflow.Transition;
import net.rubyeye.insect.workflow.WorkFlow;
import net.rubyeye.insect.workflow.WorkFlowManager;
import net.rubyeye.insect.workflow.basic.BasicWorkflowManager;
import net.rubyeye.insect.workflow.comm.TransitionType;
import net.rubyeye.insect.workflow.config.DefaultConfiguration;
import junit.framework.TestCase;

public class CompositeProcessTest extends TestCase {
    private WorkFlowManager wm;

    WorkFlow composite;

    private CyclicBarrier barrier;

    private static final int total = 1000;

    @Override
    protected void setUp() throws Exception {
        this.barrier = new CyclicBarrier(total + 1);
        wm = new BasicWorkflowManager();
        wm.setConfiguration(new DefaultConfiguration());

        WorkFlow sequence = wm.getWorkFlow("sequence");
        WorkFlow concurrency = wm.getWorkFlow("concurrency");
        WorkFlow choose = wm.getWorkFlow("choose");

        // 组合流程
        composite = new WorkFlow();
        composite.setName("composite");
        composite.setId(100);

        wm.saveWorkFlow(composite);

        // 修改开始结束节点的输入输出库所
        sequence.getEnd().setType(TransitionType.NORMAL);
        sequence.getEnd().setOutputs(concurrency.getStart().getInputs());

        concurrency.getEnd().setType(TransitionType.NORMAL);
        concurrency.getEnd().setOutputs(choose.getStart().getInputs());

        composite.setStart(sequence.getStart());
        composite.setEnd(choose.getEnd());
        List<Transition> transitions = new ArrayList<Transition>();
        transitions.addAll(sequence.getTransitions());
        transitions.addAll(concurrency.getTransitions());
        transitions.addAll(choose.getTransitions());
        composite.setTransitions(transitions);
    }

    public void testConcurrencyCompositeProcesss() throws Exception {
        for (int i = 0; i < total; i++) {
            new FlowThread().start();
        }
        barrier.await();
        long start = System.currentTimeMillis();
        barrier.await();
        long end = System.currentTimeMillis();
        System.out.println("创建" + total + "个流程并发运行完毕\n花费时间:" + (end - start)
                / 1000.0 + "秒");
        for (Transition transition : composite.getTransitions()) {
            System.out.println(transition.getName() + "  "
                    + transition.isEnable());
            for (Place place : transition.getOutputs()) {
                System.out.println("place " + place.getId() + " "
                        + place.getTokens().size());
            }
        }
    }

    public void testCompositeProcesss() throws Exception {
        long start = System.currentTimeMillis();
        for (int i = 0; i < total; i++) {
            Token token1 = wm.startWorkFlow("composite");
            token1.setAttribute("name", "dennis");
            token1.setAttribute("num", 21);
            wm.doAction(token1.getId());
            assertTrue(token1.isFinished());
        }
        long end = System.currentTimeMillis();
        System.out.println("创建" + total + "个流程运行完毕\n花费时间:" + (end - start)
                / 1000.0 + "秒");
    }

    class FlowThread extends Thread {

        @Override
        public void run() {
            try {
                barrier.await();
                // wm = new BasicWorkflowManager();
                Token token1 = wm.startWorkFlow("composite");
                token1.setAttribute("name", "dennis");
                token1.setAttribute("num", 21);
                wm.doAction(token1.getId());
                assertTrue(token1.isFinished());
                barrier.await();
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }

    }
}

文章转自庄周梦蝶  ,原文发布时间 2007-10-12

时间: 2024-09-22 12:23:13

写一个简单的工作流(三)的相关文章

写一个简单的工作流,基于petri网

写一个简单的工作流一直停留在我的"计划"中,最近趁改造绩效系统的机会,决定自己写一个基于petri网原理的工作流来改写绩效考核流程部分.基于petri网的工作流的基本算法,就是当每一个firing发生后,应当遍历整个流程重新改变transition的enable,那么当资源驱动某个transition其实就是将它的输入place中的token转移到输出place.大概的接口类似: WorkFlowManager wm = new BasicWorkflowManager(this.wo

写一个简单的工作流(四)资源的处理

昨天晚上搞到深夜,终于将资源模块搞定.到今天已经完成的功能包括: 1.四种基本路由:顺序.选择.并行.循环 2.流程定义文件和系统配置文件的读取和解析 3.使用内存作为流程数据和案例数据存储的MemoryWorkFlowDAO的开发 4.资源模块的开发 5.并发情况下的正确性测试等     计划中的功能: 1.一个GUI的流程定义工具,这个不急,也还没想好用什么做,web还是桌面? 2.各个数据库版本的WorkFlowDAO的开发,将流程数据和案例数据保存在数据库中. 3.更多的测试和examp

写一个简单的工作流(二)

    hoho,今天完成了选择路由的实现,完成了配置文件的读写和解析,流程定义文件还是决定采用xml文件,不过与其他工作流引擎采用的xml完全不同,因为是基于petri网的,因此引入了place的概念,比如下面这个4个节点的顺序路由的流程: <workflow maxCases="100">     <node type="start" name="start" id="0">         <

使用Spring来创建一个简单的工作流引擎_Java编程

文章来源:matrix 作者:Steve Dodge 摘要 spring是支持控制反转编程机制的一个相对新的框架.本文把spring作为简单工作流引擎,将它用在了更加通用的地方.在对工作流简单介绍之后,将要介绍在基本工作流场景中基于Spring的工作流API的使用. 许多J2EE应用程序要求在一个和主机分离的上下文中执行处理过程.在许多情况下,这些后台的进程执行多个任务,一些任务依赖于以前任务的状态.由于这些处理任务之间存在相互依赖的关系,使用一套基于过程的方法调用常常不能满足要求.开发人员能够

学习servlet,写一个简单的Helloword出现404错误

问题描述 学习servlet,写一个简单的Helloword出现404错误 解决方案 不需要 /servlet 解决方案二: 解决方案三: web.xml内容贴下来看看. 可以参考 我写的http://blog.csdn.net/evankaka/article/details/45151569 解决方案四: url里把[/Hello]改成[/HelloServlet] 和你Web.xml里配置的url-pattern一样. 解决方案五: 一个简单的Servlet 解决方案六: 采用servle

c++-写一个简单的二叉树遇到了segmentation fault :11问题,求助

问题描述 写一个简单的二叉树遇到了segmentation fault :11问题,求助 本人小白,写了个简单的二叉树练习一下,代码如下,运行时会出现segmentation fault :11错误,求助各位大大帮忙看看是什么原因? #include <iostream> #include <fstream> using namespace std; class Node { private: int content; Node *left; Node *right; public

checkbox-刚学完JS和servlet,写一个简单的注册登录页面

问题描述 刚学完JS和servlet,写一个简单的注册登录页面 ,想把checkbox选中的的数据和下拉列表选中的的年月日组合成字符串发送给servlet,该怎么做,求大神指教 解决方案 username: password: 表单 action 对应的servlet method 提交方式,对应servlet的doPost和doGet方法 在servlet中写 req.getParameter("username"); req.getParameter("password&

sdl初学问题-写一个简单文字游戏,需要学什么。

问题描述 写一个简单文字游戏,需要学什么. 简单文字游戏,有界面,有跟新什么的. 水平 初学c语言 初学sdl部分 另外誰有sdl2.0中文教程,给个链接谢谢. 解决方案 中文教程应该是没有的,初学要做游戏的话而且要C语言的话,建议用EasyX.详情可以参考:www.easyx.cn 解决方案二: http://download.csdn.net/detail/frankzdy/3481870 解决方案三: 要看你想用什么做,做成什么样的,个人觉得慕课网和w3cSchool这两个网站不错,知识很

Sql存储过程游标循环的用法及sql如何使用cursor写一个简单的循环_MsSql

用游标,和WHILE可以遍历您的查询中的每一条记录并将要求的字段传给变量进行相应的处理 ================== DECLARE @A1 VARCHAR(10), @A2 VARCHAR(10), @A3 INT DECLARE CURSOR YOUCURNAME FOR SELECT A1,A2,A3 FROM YOUTABLENAME OPEN YOUCURNAME fetch next from youcurname into @a1,@a2,@a3 while @@fetch