2017-02-27 41 views
1

我有一个接口说VegetableCreation与方法:有一个接口两种不同的实现在不同的线程中执行

public void writeVeggieDataIntoFile(); 

和两个不同的类名为AppleMango实现VegetableCreation

而且还有一个工厂类VegetableFactorycreate()方法:

public class VegetableFactory { 
    public VegetableCreation create(String arg0) { 

     if (arg0.equals("Apple")) 
      return new Apple(); 
     else if (arg0.equals("Mango") 
      return new Mango(); 
     else { 
      // create and return both apple and mango by spawning two different threads 
      // so that the writeVeggieDataIntoFile(); gets invoked concurrently 
      // for both apple and mango and two different file is created 
     } 
    } 
} 

什么基本上,我想在这里实现的是,当我把从客户端类的main()方法并传递VegetableFactory类的create()方法作为运行时参数的除"Apple""Mango"以外的任何字符串值。我想要两个不同的线程在每个AppleMango对象上工作,并在每个writeVeggieDataIntoFile()方法上同时工作。

任何关于设计策略的建议/或哪些并发的API使用等将受到高度赞赏。

P.S:我应该叫它水果**,而不是蔬菜*

+0

这很简单。你有什么策略 – hhafeez

+0

练习的目标是什么?学习低级线程处理?学习如何使用执行者?学习如何使用并行流?这看起来不像一个典型的使用多线程的用例,所以选择你想学的东西(或者你的老师希望你学习的东西)。 –

+0

@JBNizet我需要这样做来编写两个不同的相当大的文件。苹果和芒果只是一个例子。如果我按顺序执行该过程,则速度太慢。我在现实生活中几乎没有做过太多的线程处理,所以想要真正小心我的设计。 – shashwatZing

回答

1

查看Composite模式,然后构建一个CompositeVegetable,当它被告知“做它的事情”时,会启动两个线程,一个做一件事,另一件做另一件事。

public class BothVegetable implements Vegetable { 
    public void writeVeggieDataInfoFile() { 
     Thread thread1 = new Thread(new AppleRunnable()); 
     Thread thread2 = new Thread(new MangoRunnable()); 
     thread1.start(); 
     thread2.start(); 
     thread1.join(); 
     thread2.join(); 
    } 
} 

// and in your factory 

    return new CompositeVegetable(); 

PS。你的蔬菜看起来像水果给我!

+0

谢谢@Edwin Buck。我会试一试,如果它有效,我想提前感谢你。我确实在P.S的问题上写了一个P.:我应该叫它水果**而不是蔬菜*。只是懒惰地改变它到处都是。 – shashwatZing

+0

我假设'BothVegetable'应该重命名为'CompositeVegetable','doIt()'重命名为'writeVeggieDataIntoFile()'? – Gray

+0

是的,他们应该。除了其他CompositeVegetables可能存在,所以需要提出一个更好的名称,不排除其他CompositeVegetables。也许是'AppleMangoBlastVegetable'? –

-1

首先我会对你的工厂有静态创建。然后在Create do item instanceof Fruit中创建水果线程。否则,如果项目instanceof蔬菜然后做蔬菜线程。

+0

虽然静态方法对于工厂来说是典型的,但请记住,如果您不使用静态方法,则可以有多个工厂实例,这在试图更换工厂时非常有用。没有静态的代码基本上是相同的,只需要重用相同的实例。 –

+0

你是否投了弃权票? –

+0

不,我不是,但我看到我的回答也是反对票。 –

0

我希望得到从工厂Vegetable/Fruit称为VegetableFactory/FruitFactory,而不是一个VegetableCreation/FruitCreation

我会避免线程创建和文件写作工厂方法内的副作用。

我还重命名/改变writeFruitDataIntoFile()write(Writer out),因为你写的东西被封闭接口或类,并在那里你写由其方法参数(S)告诉告诉。

如果您确实需要并发处理,请在write(...)中创建一个线程,并让工厂方法只返回Fruit

优点是:

  • 没有副作用,在创建对象必须被记录在案。
  • 线程仅根据需求创建(如果调用write()),而不是每创建一个对象Fruit
  • 你不需要额外的类。
  • 这是一个熟悉工厂设计模式的人一见钟情的清晰实现。

参见:

对于好的OO实践的缘故,我会用一个接口:

interface Fruit { 

    void write(Writer out); 

    ... 
} // Fruit 

的抽象实现它:

public abstract class AbstractFruit implements Fruit { 

    Data data; 

    public void write(Writer out) { 
    ... 
    } 

    ... 
} // AbstractFruit 

 

public classe Apple extends AbstractFruit implements Fruit { 
    ... 
} 

 

public classe Mango extends AbstractFruit implements Fruit { 
    ... 
} 

并为type safety起见,我会使用特定get...()方法(因为它往往是done in the Java API):

public class FruitFactory { 

    public static Fruit getApple() { 
    Fruit a = new Apple() 
    ... 
    return a; 
    } 

    public static Fruit getMango() { 
    Fruit m = new Mango() 
    ... 
    return m; 
    } 
} // FruitFactory 

enum

interface Fruit { 

    enum Type { 
    APPLE, 
    MANGO 
    } 

    void write(Writer out); 

    ... 
} // Fruit 

 

public class FruitFactory { 

    public static Fruit get(Fruit.Type fruitType) { 

    switch (fruitType) { 
     case Fruit.Type.APPLE: 
      Fruit a = new Apple() 
      ... 
      return a; 
      break; 
     case Fruit.Type.MANGO: 
      Fruit m = new Mango() 
      ... 
      return m; 
      break; 
     default: 
      throw new FruitTypeNotSupported/* Runtime, i.e. unchecked */Exception(); 
      break; 
    } 
    } // get(...) 
} // FruitFactory 

RuntimeException API文档:

未检查异常不需要在方法声明[ ...]抛出子句