文档章节

Tiny并行计算框架之复杂示例

悠悠然然
 悠悠然然
发布于 2014/01/28 10:58
字数 2269
阅读 2833
收藏 61
点赞 9
评论 12

问题来源

非常感谢@doctorwho的问题:

假如职业介绍所来了一批生产汽车的工作,假设生产一辆汽车任务是这样的:搭好底盘、拧4个轮胎、安装发动机、安装4个座椅、再装4个车门、最后安装顶棚。之间有的任务是可以并行计算的(比如拧4个轮胎,安装发动机和安装座椅),有的任务有前置任务(比如先装好座椅,才能装车门和顶棚)。让两组包工头组织两种类型的工作:将工人分成两种类型,即可并行计算的放在同一组内,由职业介绍所来控制A组包工头做完的任务交给B组包工头。中间环节的半成品保存到Warehouse中,是这样使用TINY框架来生产汽车么?

接下来,我就用Tiny并行计算框架来展示一下这个示例,在编写示例的时候,发现了一个BUG,这也充分体现了开源的精神与价值,再次感谢@doctorwho。

问题分析

doctorwho的问题还是比较复杂的,但是实际上道理是一样的,因此我把问题简化成下面的过程

第一步:构建底盘

第二步:并行进行安装引擎,座位和轮胎

第三步:并行进行安装门及车顶

由于我和doctorwho都不是造车行家,因此就不用纠结这么造是不是合理了,假设这么做就是合理的。

代码实现

按我前面说的过程,工人是必须要有的,因此我们首先构建工人:

第一步的底盘构建工人

public class StepFirstWorker extends AbstractWorker {
    public StepFirstWorker() throws RemoteException {
        super("first");
    }

    @Override
    protected Warehouse doWork(Work work) throws RemoteException {
        System.out.println(String.format("%s 构建底盘完成.", work.getInputWarehouse().get("carType")));
        Warehouse outputWarehouse = work.getInputWarehouse();
        outputWarehouse.put("baseInfo", "something about baseInfo");
        return outputWarehouse;
    }
}

由于第二步工人有好几个类型,因此再搞个第二步抽象工人:

public abstract class StepThirdWorker extends AbstractWorker {
    public StepThirdWorker() throws RemoteException {
        super("third");
    }


    protected boolean acceptMyWork(Work work) {
        String workClass = work.getInputWarehouse().get("class");
        if (workClass != null) {
            return true;
        }
        return false;
    }
    protected Warehouse doMyWork(Work work) throws RemoteException {
        System.out.println(String.format("Base:%s ", work.getInputWarehouse().get("baseInfo")));
        System.out.println(String.format("%s is Ok", work.getInputWarehouse().get("class")));
        return work.getInputWarehouse();
    }
}

接下来构建第二步的引擎工人:

public class StepSecondEngineWorker extends StepSecondWorker {


 public static final String ENGINE = "engine";


 public StepSecondEngineWorker() throws RemoteException {
 super();
 }


 public boolean acceptWork(Work work) {
 return acceptMyWork(work);
 }


 protected Warehouse doWork(Work work) throws RemoteException {
 return super.doMyWork(work);
 }
}

第二步的座位工人:

public class StepSecondSeatWorker extends StepSecondWorker {


    public static final String SEAT = "seat";


    public StepSecondSeatWorker() throws RemoteException {
        super();
    }
    public boolean acceptWork(Work work) {
       return acceptMyWork(work);
    }
    protected Warehouse doWork(Work work) throws RemoteException {
        return super.doMyWork(work);
    }
}


  
  

第二步的轮胎工人:

public class StepSecondTyreWorker extends StepSecondWorker {
 public static final String TYRE = "tyre";


 public StepSecondTyreWorker() throws RemoteException {
 super();
 }


 public boolean acceptWork(Work work) {
 return acceptMyWork(work);
 }


 protected Warehouse doWork(Work work) throws RemoteException {
 return super.doMyWork(work);
 }
}

同理,第三步也是大同小异的。

第三步的抽象工人类:

public abstract class StepThirdWorker extends AbstractWorker {
    public StepThirdWorker() throws RemoteException {
        super("third");
    }


    protected boolean acceptMyWork(Work work) {
        String workClass = work.getInputWarehouse().get("class");
        if (workClass != null) {
            return true;
        }
        return false;
    }
    protected Warehouse doMyWork(Work work) throws RemoteException {
        System.out.println(String.format("Base:%s ", work.getInputWarehouse().get("baseInfo")));
        System.out.println(String.format("%s is Ok", work.getInputWarehouse().get("class")));
        return work.getInputWarehouse();
    }
}

第三步的车门工人:

public class StepThirdDoorWorker extends StepThirdWorker {


    public static final String DOOR = "door";


    public StepThirdDoorWorker() throws RemoteException {
        super();
    }
    public boolean acceptWork(Work work) {
        return acceptMyWork(work);
    }
    @Override
    protected Warehouse doWork(Work work) throws RemoteException {
        return super.doMyWork(work);
    }
}

第三步的车顶工人:

public class StepThirdRoofWorker extends StepThirdWorker {


    public static final String ROOF = "roof";


    public StepThirdRoofWorker() throws RemoteException {
        super();
    }
    public boolean acceptWork(Work work) {
        return acceptMyWork(work);
    }
    protected Warehouse doWork(Work work) throws RemoteException {
        return super.doMyWork(work);
    }
}

以上就把工人都构建好了,我们前面也说过,如果要进行任务分解,是必须要构建任务分解合并器的,这里简单起见,只实现任务分解了。

第二部的任务分解:

public class SecondWorkSplitter implements WorkSplitter {
    public List<Warehouse> split(Work work, List<Worker> workers) throws RemoteException {
        List<Warehouse> list = new ArrayList<Warehouse>();
        list.add(getWareHouse(work.getInputWarehouse(), "engine"));
        list.add(getWareHouse(work.getInputWarehouse(), "seat"));
        list.add(getWareHouse(work.getInputWarehouse(), "seat"));
        list.add(getWareHouse(work.getInputWarehouse(), "seat"));
        list.add(getWareHouse(work.getInputWarehouse(), "seat"));
        list.add(getWareHouse(work.getInputWarehouse(), "tyre"));
        list.add(getWareHouse(work.getInputWarehouse(), "tyre"));
        list.add(getWareHouse(work.getInputWarehouse(), "tyre"));
        list.add(getWareHouse(work.getInputWarehouse(), "tyre"));
        return list;
    }

    private Warehouse getWareHouse(Warehouse inputWarehouse, String stepClass) {
        Warehouse warehouse = new WarehouseDefault();
        warehouse.put("class", stepClass);
        warehouse.putSubWarehouse(inputWarehouse);
        return warehouse;
    }
}

从上面可以看到,构建了一个引擎的仓库,4个座位仓库,4个轮胎仓库。呵呵,既然能并行,为啥不让他做得更快些?

接下来是第三步的任务分解器:

public class ThirdWorkSplitter implements WorkSplitter {
    public List<Warehouse> split(Work work, List<Worker> workers) throws RemoteException {
        List<Warehouse> list = new ArrayList<Warehouse>();
        list.add(getWareHouse(work.getInputWarehouse(), "door"));
        list.add(getWareHouse(work.getInputWarehouse(), "door"));
        list.add(getWareHouse(work.getInputWarehouse(), "door"));
        list.add(getWareHouse(work.getInputWarehouse(), "door"));
        list.add(getWareHouse(work.getInputWarehouse(), "roof"));
        return list;
    }

    private Warehouse getWareHouse(Warehouse inputWarehouse, String stepClass) {
        Warehouse warehouse = new WarehouseDefault();
        warehouse.put("class", stepClass);
        warehouse.putSubWarehouse(inputWarehouse);
        return warehouse;
    }
}

从上面可以看到,第三部构建了4个门仓库一个车顶仓库,同样的,可以让4个工人同时装门。

上面就把所有的准备工作都做好了,接下来就是测试方法了:

public class Test {
    public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
        JobCenter jobCenter = new JobCenterLocal();


        for (int i = 0; i < 5; i++) {
            jobCenter.registerWorker(new StepFirstWorker());
        }
        for (int i = 0; i < 5; i++) {
            jobCenter.registerWorker(new StepSecondTyreWorker());
        }
        for (int i = 0; i < 5; i++) {
            jobCenter.registerWorker(new StepSecondSeatWorker());
        }
        for (int i = 0; i < 5; i++) {
            jobCenter.registerWorker(new StepSecondEngineWorker());
        }
        for (int i = 0; i < 5; i++) {
            jobCenter.registerWorker(new StepThirdDoorWorker());
        }
        for (int i = 0; i < 5; i++) {
            jobCenter.registerWorker(new StepThirdRoofWorker());
        }

        jobCenter.registerForeman(new ForemanSelectOneWorker("first"));
      jobCenter.registerForeman(new ForemanSelectAllWorker("second",
 new SecondWorkSplitter()));
 jobCenter.registerForeman(new ForemanSelectAllWorker("third",new ThirdWorkSplitter()));


 Warehouse inputWarehouse = new WarehouseDefault();
 inputWarehouse.put("class", "car");
 inputWarehouse.put("carType", "普桑");
 WorkDefault work = new WorkDefault("first", inputWarehouse);
 work.setForemanType("first");
 WorkDefault work2 = new WorkDefault("second");
 work2.setForemanType("second");
 WorkDefault work3 = new WorkDefault("third");
 work3.setForemanType("third");
 work.setNextWork(work2).setNextWork(work3);


 Warehouse warehouse = jobCenter.doWork(work);


 jobCenter.stop();

    }
}

呵呵,工人各加了5个,然后注册了三个工头,第一步的工头是随便挑一个工人类型的,第二步和第三步是挑所有工人的,同时还指定了任务分解器。

接下来就构建了一个工作,造一个高端大气上档次的普桑汽车,然后告诉职业介绍所说给我造就可以了。

下面是造车的过程,我把日志也贴上来了:

普桑 构建底盘完成.
-234  [RMI TCP Connection(1)-192.168.84.73] INFO   - 线程组<id:4af96b81d14a4954a6b649308d444e4c,type:second>运行开始,线程数9...
-234  [id:4af96b81d14a4954a6b649308d444e4c,type:second-a763f156ffd74b5db285198d2498edcf] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-a763f156ffd74b5db285198d2498edcf>运行开始...
-234  [id:4af96b81d14a4954a6b649308d444e4c,type:second-c2d2fb38ef6c4509b3a39b3e7d5c1d61] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-c2d2fb38ef6c4509b3a39b3e7d5c1d61>运行开始...
-234  [id:4af96b81d14a4954a6b649308d444e4c,type:second-d624ea0a6df3409c80df6b97ab3c813b] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-d624ea0a6df3409c80df6b97ab3c813b>运行开始...
-235  [id:4af96b81d14a4954a6b649308d444e4c,type:second-abdb57f0641a4727a9efa744d07cf2d1] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-abdb57f0641a4727a9efa744d07cf2d1>运行开始...
-236  [id:4af96b81d14a4954a6b649308d444e4c,type:second-d6f7074f6c4a4b12bd37ec5f5c11aff8] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-d6f7074f6c4a4b12bd37ec5f5c11aff8>运行开始...
-237  [id:4af96b81d14a4954a6b649308d444e4c,type:second-04db3f945b804500a2bbe2b9aabdce3b] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-04db3f945b804500a2bbe2b9aabdce3b>运行开始...
Base:something about baseInfo 
engine is Ok
Base:something about baseInfo 
seat is Ok
-245  [id:4af96b81d14a4954a6b649308d444e4c,type:second-a763f156ffd74b5db285198d2498edcf] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-a763f156ffd74b5db285198d2498edcf>运行结束
-246  [id:4af96b81d14a4954a6b649308d444e4c,type:second-f3efba2dc7804c6cbcd5a25f42fdc177] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-f3efba2dc7804c6cbcd5a25f42fdc177>运行开始...
-246  [id:4af96b81d14a4954a6b649308d444e4c,type:second-abdb57f0641a4727a9efa744d07cf2d1] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-abdb57f0641a4727a9efa744d07cf2d1>运行结束
Base:something about baseInfo 
seat is Ok
-248  [id:4af96b81d14a4954a6b649308d444e4c,type:second-8c3b9359bcfa4de7b6e0492daab0d73a] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-8c3b9359bcfa4de7b6e0492daab0d73a>运行开始...
Base:something about baseInfo 
tyre is Ok
-250  [id:4af96b81d14a4954a6b649308d444e4c,type:second-f3efba2dc7804c6cbcd5a25f42fdc177] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-f3efba2dc7804c6cbcd5a25f42fdc177>运行结束
-250  [id:4af96b81d14a4954a6b649308d444e4c,type:second-c2d2fb38ef6c4509b3a39b3e7d5c1d61] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-c2d2fb38ef6c4509b3a39b3e7d5c1d61>运行结束
Base:something about baseInfo 
seat is Ok
-252  [id:4af96b81d14a4954a6b649308d444e4c,type:second-869b573e226046aca8ad30765f1f300c] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-869b573e226046aca8ad30765f1f300c>运行开始...
-253  [id:4af96b81d14a4954a6b649308d444e4c,type:second-8c3b9359bcfa4de7b6e0492daab0d73a] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-8c3b9359bcfa4de7b6e0492daab0d73a>运行结束
Base:something about baseInfo 
seat is Ok
Base:something about baseInfo 
tyre is Ok
-257  [id:4af96b81d14a4954a6b649308d444e4c,type:second-d624ea0a6df3409c80df6b97ab3c813b] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-d624ea0a6df3409c80df6b97ab3c813b>运行结束
-258  [id:4af96b81d14a4954a6b649308d444e4c,type:second-04db3f945b804500a2bbe2b9aabdce3b] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-04db3f945b804500a2bbe2b9aabdce3b>运行结束
Base:something about baseInfo 
tyre is Ok
Base:something about baseInfo 
tyre is Ok
-262  [id:4af96b81d14a4954a6b649308d444e4c,type:second-869b573e226046aca8ad30765f1f300c] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-869b573e226046aca8ad30765f1f300c>运行结束
-264  [id:4af96b81d14a4954a6b649308d444e4c,type:second-d6f7074f6c4a4b12bd37ec5f5c11aff8] INFO   - 线程<id:4af96b81d14a4954a6b649308d444e4c,type:second-d6f7074f6c4a4b12bd37ec5f5c11aff8>运行结束
-264  [RMI TCP Connection(1)-192.168.84.73] INFO   - 线程组<id:4af96b81d14a4954a6b649308d444e4c,type:second>运行结束, 用时:30ms
-333  [RMI TCP Connection(1)-192.168.84.73] INFO   - 线程组<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third>运行开始,线程数5...
-334  [id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-ca58e9b733514c668a224875417c9d26] INFO   - 线程<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-ca58e9b733514c668a224875417c9d26>运行开始...
-334  [id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-17debef817e34c49996a2c38840f3de2] INFO   - 线程<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-17debef817e34c49996a2c38840f3de2>运行开始...
-334  [id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-af0e914cce89480987c6184a885770d5] INFO   - 线程<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-af0e914cce89480987c6184a885770d5>运行开始...
-334  [id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-3f7707cb2a224d3d8844a09271b24a07] INFO   - 线程<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-3f7707cb2a224d3d8844a09271b24a07>运行开始...
Base:something about baseInfo 
door is Ok
Base:something about baseInfo 
door is Ok
Base:something about baseInfo 
-338  [id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-ca58e9b733514c668a224875417c9d26] INFO   - 线程<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-ca58e9b733514c668a224875417c9d26>运行结束
door is Ok
-339  [id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-cfccfb37ebda4279b7552f7e060b2ddb] INFO   - 线程<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-cfccfb37ebda4279b7552f7e060b2ddb>运行开始...
-338  [id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-17debef817e34c49996a2c38840f3de2] INFO   - 线程<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-17debef817e34c49996a2c38840f3de2>运行结束
Base:something about baseInfo 
door is Ok
Base:something about baseInfo 
-340  [id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-3f7707cb2a224d3d8844a09271b24a07] INFO   - 线程<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-3f7707cb2a224d3d8844a09271b24a07>运行结束
roof is Ok
-340  [id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-af0e914cce89480987c6184a885770d5] INFO   - 线程<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-af0e914cce89480987c6184a885770d5>运行结束
-342  [id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-cfccfb37ebda4279b7552f7e060b2ddb] INFO   - 线程<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third-cfccfb37ebda4279b7552f7e060b2ddb>运行结束
-343  [RMI TCP Connection(1)-192.168.84.73] INFO   - 线程组<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third>运行结束, 用时:10ms

从上面的日志可以看出:

由于第一步工作是挑一个单干的,因此是没有启用线程组的

第二步同时有9个线程干活:

-234  [RMI TCP Connection(1)-192.168.84.73] INFO   - 线程组<id:4af96b81d14a4954a6b649308d444e4c,type:second>运行开始,线程数9...
...
-264  [RMI TCP Connection(1)-192.168.84.73] INFO   - 线程组<id:4af96b81d14a4954a6b649308d444e4c,type:second>运行结束, 用时:30ms

第三步同时有5个线程干活:

-333  [RMI TCP Connection(1)-192.168.84.73] INFO   - 线程组<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third>运行开始,线程数5...
...
-343  [RMI TCP Connection(1)-192.168.84.73] INFO   - 线程组<id:9b0de678632d4fb8b87ae9db4b6436f8,type:third>运行结束, 用时:10ms

总结:

Tiny并行计算框架确实是可以方便的解决各种复杂并行计算的问题。



© 著作权归作者所有

共有 人打赏支持
悠悠然然

悠悠然然

粉丝 2365
博文 173
码字总数 360373
作品 14
杭州
架构师
加载中

评论(12)

J-Fla
J-Fla
@
悠悠然然
悠悠然然

引用来自“doctorwho”的评论

引用来自“悠悠然然”的评论

引用来自“信仰者”的评论

维护maven仓库中代码不一样?
AbstractWorker 中的abstract protected void doWork(Work work) throws RemoteException;
WorkSplitter中的void split(Work work, List<Worker> workers) throws RemoteException;
WorkCombiner中的void combine(Work work, List<Worker> workers) throws RemoteException;
均返回void,与示例代码不一致

因为开源前会增加大量的测试用例。
我们的模式是我构建主体框架或核心代码,有普通开发人员编写测试用例的。
现在测试用例还没有写,也就是是整体是通了,但是测试得还不够充分。
已经给你站内信了。

原来还有剧透的地方...

原来的设计是工人,工头都是有状态的,后来改成无状态的了,总的来说优点多于缺点。
因此接口有变化。
悠悠然然
悠悠然然

引用来自“doctorwho”的评论

引用来自“悠悠然然”的评论

@doctorwho 不知上面的演示是否解答了你的疑问?

非常感谢LZ用如此详细的例子来解答,令人豁然开朗。
工头负责分解/合并每个工人要做的任务
工人只处理一种类型的任务,因此复杂任务需要多种类型工人
工作本身由一系列前后的任务组合而成的。任务之间的产出物堆在仓库中。
职介所负责撮合工头与工人来完成指定的工作任务

总结的非常准确。
悠悠然然
悠悠然然

引用来自“doctorwho”的评论

引用来自“悠悠然然”的评论

@doctorwho 不知上面的演示是否解答了你的疑问?

再提个问题,如果要实现生产多辆同型号的汽车,是在职介所注册多份相同的生产汽车的工作任务组成工作队列?

对的,每辆汽车一个work。
队列里面自己带了,开发人员不用管的。
doctorwho
doctorwho

引用来自“悠悠然然”的评论

引用来自“信仰者”的评论

维护maven仓库中代码不一样?
AbstractWorker 中的abstract protected void doWork(Work work) throws RemoteException;
WorkSplitter中的void split(Work work, List<Worker> workers) throws RemoteException;
WorkCombiner中的void combine(Work work, List<Worker> workers) throws RemoteException;
均返回void,与示例代码不一致

因为开源前会增加大量的测试用例。
我们的模式是我构建主体框架或核心代码,有普通开发人员编写测试用例的。
现在测试用例还没有写,也就是是整体是通了,但是测试得还不够充分。
已经给你站内信了。

原来还有剧透的地方...
doctorwho
doctorwho

引用来自“悠悠然然”的评论

@doctorwho 不知上面的演示是否解答了你的疑问?

再提个问题,如果要实现生产多辆同型号的汽车,是在职介所注册多份相同的生产汽车的工作任务组成工作队列?
doctorwho
doctorwho

引用来自“悠悠然然”的评论

@doctorwho 不知上面的演示是否解答了你的疑问?

非常感谢LZ用如此详细的例子来解答,令人豁然开朗。
工头负责分解/合并每个工人要做的任务
工人只处理一种类型的任务,因此复杂任务需要多种类型工人
工作本身由一系列前后的任务组合而成的。任务之间的产出物堆在仓库中。
职介所负责撮合工头与工人来完成指定的工作任务
信仰者
79
悠悠然然
悠悠然然

引用来自“信仰者”的评论

维护maven仓库中代码不一样?
AbstractWorker 中的abstract protected void doWork(Work work) throws RemoteException;
WorkSplitter中的void split(Work work, List<Worker> workers) throws RemoteException;
WorkCombiner中的void combine(Work work, List<Worker> workers) throws RemoteException;
均返回void,与示例代码不一致

因为开源前会增加大量的测试用例。
我们的模式是我构建主体框架或核心代码,有普通开发人员编写测试用例的。
现在测试用例还没有写,也就是是整体是通了,但是测试得还不够充分。
已经给你站内信了。
悠悠然然
悠悠然然
你太厉害,居然找到maven仓库了。
这个还没有正式开源,所以还有变化。
如果想马上使用,请根据站内信息做就可以了。

Tiny群每周2,4晚上9:00视频,培训、讲解、答疑,应有尽有

部分讲解视频已上传,想查看请入群查看群共享文件《Tiny视频汇集须知.txt》: 2014-11-28 Tiny框架PPT讲解 12人 2014-11-29 Tiny框架界面开发 26人 2014-11-30 Tiny框架服务开发 37人 2014-1...

悠悠然然 ⋅ 2014/11/30 ⋅ 72

Tiny分布式计算框架开源了

源码地址: http://git.oschina.net/tinyframework/tiny http://git.oschina.net/tinyframework/tiny/tree/master/framework/org.tinygroup.pc 前面和果粉们说了,要在200果粉齐了的时候就开......

悠悠然然 ⋅ 2014/03/28 ⋅ 17

Tiny并行计算框架之实现机理

上面一篇介绍了Tiny并行计算框架之使用,这一篇呢,主要介绍其实现机理。 当然,秉承偶的一向的观点,让新手也能看得懂。 首先看工作的接口: public interface Work extends Serializable {...

悠悠然然 ⋅ 2014/01/27 ⋅ 3

从应用示例来认识Tiny框架

呵呵,Tiny框架神龙见首不见尾已经许多时间了,里面只看到一些几个孤零零的子框架。今天就通过Tiny开发示例的方式来重点展示一下利用Tiny框架是如何开发的。 HelloWorld 首先从这个神一样的示...

悠悠然然 ⋅ 2014/05/22 ⋅ 22

一年走向【Java架构师】之葵花宝典

大多数时候,不是我们不努力,而是不知从何下手,我深知一份好的学习资料是多么的重要,我们通常会把大量的时间都浪费在找资源上,本人搜集学习java架构师的经典学习路线如下可供参考!!! 一...

我一路狂奔 ⋅ 2017/05/20 ⋅ 1

《企业级JavaEE架构设计精深实践》预售结束

如果有同学还想买书,请访问连接http://item.jd.com/11944458.html 如果买了书,但是没有收到,请及时和我们联系,站内信或QQ都可以。 ==================================================...

悠悠然然 ⋅ 2015/12/28 ⋅ 86

Tiny并行计算框架之使用介绍

呵呵,昨天看到两新粉,一激动,就想着今天来写这篇文章。 其实一直在关注这个领域,但是一直没有信心来写,所以一直期望着有一个开源的来用。 看到了彭渊大师的淘宝分布式框架Fourinone介绍...

悠悠然然 ⋅ 2014/01/26 ⋅ 4

DSL风格数据库编程之实践

现在的应用系统中,绝多多数的情况下都是要用到数据库的,而适合Java框架的数据库处理方案太多了,这里就不一一列出了。 现在又比较流行一种DSL(Domain Specific Language)风格的数据库访问方...

悠悠然然 ⋅ 2015/03/12 ⋅ 5

Tiny快速入门之控制层开发

下面是一些常用的链接,供大家使用: GIT地址(必须是OSC家的):https://git.oschina.net/tinyframework/tiny 问题报告:https://git.oschina.net/tinyframework/tiny/issues 官方网站:http:...

悠悠然然 ⋅ 2014/11/27 ⋅ 8

悠然乱弹:云里雾里说Tiny

今天从杭州到重庆,登机时间晚了20分钟,又晚了20分钟,又晚了20分钟,尼玛,这和我们软件实现的进度有得一比,总是他妈的延迟、延迟再延迟。 终于登机了,可能是MH17的事情影响了我的心情,...

悠悠然然 ⋅ 2014/07/20 ⋅ 9

没有更多内容

加载失败,请刷新页面

加载更多

下一页

彻底删除Microsoft Office的方法

参照此链接彻底删除Office https://support.office.com/zh-cn/article/%e4%bb%8e-pc-%e5%8d%b8%e8%bd%bd-office-9dd49b83-264a-477a-8fcc-2fdf5dbf61d8?ui=zh-CN&rs=zh-CN&ad=CN......

Kampfer ⋅ 25分钟前 ⋅ 0

大盘与个股之间关系

大盘走多:积极出手 顺势加码 大盘走空: 少量出手 退场观望 大盘做头:逆势减码 少量操作 大盘做底 : 小量建仓 小量试单

guozenhua ⋅ 26分钟前 ⋅ 0

Day16 LVM(逻辑卷管理)与磁盘故障小案例

lvm详解 简述 LVM的产生是因为传统的分区一旦分区好后就无法在线扩充空间,也存在一些工具能实现在线扩充空间但是还是会面临数据损坏的风险;传统的分区当分区空间不足时,一般的解决办法是再...

杉下 ⋅ 33分钟前 ⋅ 0

rsync实现多台linux服务器的文件同步

一、首先安装rsync,怎样安装都行,rpm,yum,还是你用源码安装都可以。因为我用的是阿里云的ESC,yum install rsync就ok了。 二、配置rsync服务 1.先建立个同步数据的帐号 123 groupadd r...

在下头真的很硬 ⋅ 46分钟前 ⋅ 0

前端基础(三):函数

字数:1685 阅读时间:5分钟 函数定义 在最新的ES规范中,声明函数有4中方法: -函数声明 -函数表达式 -构造函数Function -生成器函数 1.函数声明 语法: function name([param[, param2 [....

老司机带你撸代码 ⋅ 今天 ⋅ 0

Java虚拟机的Heap监狱

在Java虚拟机中,我是一个位高权重的大管家,他们都很怕我,尤其是那些Java 对象,我把他们圈到一个叫做Heap的“监狱”里,严格管理,生杀大权尽在掌握。 中国人把Stack翻译成“栈”,把Hea...

java高级架构牛人 ⋅ 今天 ⋅ 0

Spring MVC基本概念

只写Controller

颖伙虫 ⋅ 今天 ⋅ 0

微软重金收购GitHub的背后逻辑原来是这样的

全球最大的开发者社区GitHub网站花落谁家的问题已经敲定,微软最终以75亿美元迎娶了这位在外界看来无比“神秘”的小家碧玉。尽管此事已过去一些时日,但整个开发者世界,包括全球各地的开源社...

linux-tao ⋅ 今天 ⋅ 0

磁盘管理—逻辑卷lvm

4.10-4.12 lvm 操作流程: 磁盘分区-->创建物理卷-->划分为卷组-->划分成逻辑卷-->格式化、挂载-->扩容。 磁盘分区 注: 创建分区时需要更改其文件类型为lvm(代码8e) 分区 3 已设置为 Linu...

弓正 ⋅ 今天 ⋅ 0

Spring源码解析(六)——实例创建(上)

前言 经过前期所有的准备工作,Spring已经获取到需要创建实例的 beanName 和对应创建所需要信息 BeanDefinition,接下来就是实例创建的过程,由于该过程涉及到大量源码,所以将分为多个章节进...

MarvelCode ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部