问题来源  很感谢@doctorwho的问题:

假如职业介绍所来了一批生产汽车的工作,如果生产一辆汽车任务是这种:搭好底盘、拧4个轮胎、安装发动机、安装4个座椅、再装4个车门、最后安装顶棚。

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


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


问题分析


doctorwho的问题还是比較复杂的。可是实际上道理是一样的。因此我把问题简化成以下的过程


第一步:构建底盘


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



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


因为我和doctorwho都不是造车行家,因此就不用纠结这么造是不是合理了,如果这么做就是合理的。

代码实现


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


第一步的底盘构建工人

1

2

3

4

5

6

7

8

9

10

11

12

13
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;

    }

}

因为第二步工人有好几个类型。因此再搞个第二步抽象工人:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19
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();

    }

}

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20
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);

}

}

第二步的座位工人:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21
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);

    }

}



<div>





</div>

第二步的轮胎工人:



?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
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);

}

}

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

第三步的抽象工人类:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19
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();

    }

}

第三步的车门工人:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17
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);

    }

}

第三步的车顶工人:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16
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);

    }

}

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

第二部的任务分解:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22
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个轮胎仓库。呵呵,既然能并行。为啥不让他做得更快些?


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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18
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个工人同一时候装门。

上面就把全部的准备工作都做好了,接下来就是測试方法了:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49
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"));

     <span></span> <span></span>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个。然后注冊了三个工头,第一步的工头是随便挑一个工人类型的。第二步和第三步是挑全部工人的。同一时候还指定了任务分解器。


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


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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61
普桑 构建底盘完毕.

-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个线程干活:

1

2

3
-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个线程干活:

1

2

3
-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并行计算框架确实是能够方便的解决各种复杂并行计算的问题。

Tiny并行计算框架之复杂演示样例的更多相关文章

  1. java并行调度框架封装及演示样例

    參考资料:  阿里巴巴开源项目 CobarClient  源代码实现. 分享作者:闫建忠 分享时间:2014年5月7日 ---------------------------------------- ...

  2. Python Web框架Tornado的异步处理代码演示样例

    1. What is Tornado Tornado是一个轻量级但高性能的Python web框架,与还有一个流行的Python web框架Django相比.tornado不提供操作数据库的ORM接口 ...

  3. android listview综合使用演示样例_结合数据库操作和listitem单击长按等事件处理

    本演示样例说明: 1.自己定义listview条目样式,自己定义listview显示列数的多少,灵活与数据库中字段绑定. 2.实现对DB的增删改查,而且操作后listview自己主动刷新. 3.响应用 ...

  4. Thrift的安装和简单演示样例

    本文仅仅是简单的解说Thrift开源框架的安装和简单使用演示样例.对于具体的解说,后面在进行阐述. Thrift简述                                           ...

  5. [hadoop系列]Pig的安装和简单演示样例

    inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ).(来源:http://blog.csdn.net/inkfish) Pig是Yaho ...

  6. SNF快速开发平台MVC-各种级联绑定方式,演示样例程序(包含表单和表格控件)

    做了这么多项目,经常会使用到级联.联动的情况. 如:省.市.县.区.一级分类.二级分类.三级分类.仓库.货位. 方式:有表单需要做级联的,还是表格行上需要做级联操作的. 实现:实现方法也有很多种方式. ...

  7. 通过Canvas及File API缩放并上传图片完整演示样例

    创建一个只管的用户界面,并同意你控制图片的大小.上传到server端的数据,并不须要处理enctype为 multi-part/form-data 的情况.只一个简单的POST表单处理程序就能够了. ...

  8. 01_MUI之Boilerplate中:HTML5演示样例,动态组件,自己定义字体演示样例,自己定义字体演示样例,图标字体演示样例

     1安装HBuilder5.0.0,安装后的界面截图例如以下: 2 依照https://www.muicss.com/docs/v1/css-js/boilerplate-html中的说明,创建上 ...

  9. 移动端报表JS开发演示样例

    近期对移动端的报表开发颇有研究,细磨精算了好久,尽管到如今还是"囊中羞涩",但决定还是先抛砖引玉,拿点小干货出来和大家分享. 研究的工具是比較有代表性的FineReport. 1. ...

随机推荐

  1. 【PAT】1041. Be Unique (20)

    题目链接:http://pat.zju.edu.cn/contests/pat-a-practise/1041 题目描述: Being unique is so important to people ...

  2. HDU 2896 病毒侵袭 AC自己主动机题解

    本题是在text里面查找key word的增强版.由于这里有多个text. 那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术.我直接使用个vis数组记录已经訪问过的节点, ...

  3. 软件下载网(包括MAC软件大全)

    http://www.ddooo.com/ MAC软件大全: http://www.ddooo.com/apple/15_5_1.htm

  4. mysql死锁问题分析(转)

    线上某服务时不时报出如下异常(大约一天二十多次):“Deadlock found when trying to get lock;”. Oh, My God! 是死锁问题.尽管报错不多,对性能目前看来 ...

  5. SOLR搭建企业搜索平台

    一. SOLR搭建企业搜索平台  运行环境:  运行容器:Tomcat6.0.20  Solr版本:apache-solr-1.4.0  分词器:mmseg4j-1.6.2  词库:sogou-dic ...

  6. python gzip 压缩文件

    压缩数据创建gzip文件 先看一个略麻烦的做法 ? 1 2 3 4 5 6 import StringIO,gzip content = 'Life is short.I use python' zb ...

  7. bottle-session 0.3 : Python Package Index

    bottle-session 0.3 : Python Package Index bottle-session 0.3

  8. NotePad++ 快捷键中文说明

    Ctrl-H 打开Find / Replace 对话框 Ctrl-D 复制当前行 Ctrl-L 删除当前行 Ctrl-T 上下行交换 F3 找下一个 Shift-F3 找上一个 Ctrl-Shift- ...

  9. ARM过程调用标准---APCS简单介绍

    介绍 APCS,ARM 过程调用标准(ARM Procedure Call Standard),提供了紧凑的编写例程的一种机制,定义的例程能够与其它例程交织在一起.最显著的一点是对这些例程来自哪里没有 ...

  10. 创建了一个基于最短路径规划geoserver的wms服务

    两点之间的文章书面请求随机最短路径sql功能,这篇文章是关于如何将上述到系统中的子功能. 1.geoserver登录 首先单击geoserver安装路径下的start Geoserver 待geose ...