2017-02-27 45 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文檔:

未檢查異常不需要在方法聲明[ ...]拋出子句