2014-03-04 101 views
3

嗯好的,廣東話混合牛奶和咖啡在我的杯子

由於觀察點模式的超重在這裏,我用我自己的嘗試。

不知何故咖啡或牛奶不放在杯子裏。

package test; 
import java.util.*; 
public class Task extends Thread { 

    private static final Task EMPTY_TASK = null; 

    private Task postTask = EMPTY_TASK; 
    private final List<Task> preconditions; 

    public Task() { 
     super(); 
     preconditions = Collections.emptyList(); 
    } 

    public Task(final String name, final Task... preliminaries) { 
     super(name); 
     this.preconditions = new ArrayList<Task>(Arrays.asList(preliminaries)); 
     for (Task preliminary : preliminaries) { 
      preliminary.setPostTask(this); 
     } 
    } 

    private void setPostTask(final Task postTask) { 
     this.postTask = postTask; 
    } 

    @Override 
    public void run() { 
     System.out.println("Working " + this); 
     if (postTask != null) { 
      postTask.informSolved(this); 
     } 
    } 

    @Override 
    public synchronized void start() { 
     if (preconditions.size() == 0) { 
      super.start(); 
     } else { 
      System.out.println("The " + getName() + " cant start: " + preconditions 
        + " not yet solved."); 
     } 
    } 

    private synchronized void informSolved(final Task task) { 
     preconditions.remove(task); 
     start(); 
    } 

    @Override 
    public String toString() { 
     return getName(); 
    } 

    public static void main(final String[] args) { 
     Task cup = new Task("Cup"); 
     Task milk = new Task("Milk", cup); 
     Task coffee = new Task("Coffee", cup); 
     Task mix = new Task("Mix", milk, coffee); 

     mix.start(); 
     milk.start(); 
     cup.start(); 
     coffee.start(); 
    } 
} 

這顯示在控制檯上:

The Mix cant start: [Milk, Coffee] not yet solved. 
The Milk cant start: [Cup] not yet solved. 
The Coffee cant start: [Cup] not yet solved. 
Working Cup 
Working Coffee 
The Mix cant start: [Milk] not yet solved. 

我的問題:我有什麼做的就是我的咖啡混合使用嗎?

+16

當我讀你的標題時,我以爲我很高。 – Maroun

+3

,而任務可能有許多預備,每個初步任務只能有一個任務。但在你的例子中,「杯子」應該有2個任務 - >牛奶和咖啡。所以用「addPostTask」邏輯改變「setPostTask」,你很好。 – frail

+0

@frail多數民衆贊成它!謝謝 –

回答

3

這就是爲什麼你不能有你早上喝咖啡:

private void setPostTask(final Task postTask) { 
    this.postTask = postTask; 
} 

任務只能有一個崗位的任務,你的情況杯需要有2 - 咖啡和牛奶。使postTask成爲postTask

1

請注意,延伸Thread s的整個方法是值得懷疑的。下面是一個更受推薦的編程風格的例子:

import java.util.Arrays; 
import java.util.Collections; 
import java.util.List; 
import java.util.concurrent.*; 

public class CoffeeMixing 
{ 
    public static void main(String[] args) 
    { 
    new CoffeeMixing().mix(); 
    } 
    private void mix() 
    { 
    ExecutorService e=Executors.newCachedThreadPool(); 
    Future<?> cup=e.submit(new Task("cup")); 
    Future<?> milk=e.submit(new Task("Milk", cup)); 
    Future<?> coffee=e.submit(new Task("Coffee", cup)); 
    Future<?> mix=e.submit(new Task("Mix", milk, coffee)); 
    try 
    { 
     mix.get(); 
     System.out.println("Now I have my coffee"); 
    } 
    catch(ExecutionException | InterruptedException ex) 
    { 
     System.out.println("while trying to get coffee: "+ex); 
    } 
    } 
    final class Task implements Callable<Void> 
    { 
    private final String name; 
    private final List<Future<?>> preconditions; 

    Task(String name) 
    { 
     this.name=name; 
     preconditions=Collections.emptyList(); 
    } 
    Task(String name, Future<?>... pre) 
    { 
     this.name=name; 
     preconditions=Arrays.asList(pre); 
    } 
    public Void call() throws Exception 
    { 
     if(!preconditions.isEmpty()) 
     { 
     System.out.println(name+" awaiting preconditions"); 
     for(Future<?> f: preconditions) f.get(); 
     } 
     System.out.println("Working "+name); 
     return null; 
    } 
    } 
} 
+0

牛奶和咖啡是否執行異步? 'void call'在內部使用循環。 –

+0

所有這些都是異步執行的。 ['Future.get()'](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#get())等待異步完成。但是,如果它們足夠快地完成,那麼'ExecutorService'將在下一個'Task'中重用那個免費的'Thread'。 – Holger

+1

爲了「等待」幾毫秒是一種推薦的編程風格?即使是量子計算機也需要至少3ms而不是1ms。如果我花三倍的時間製作咖啡,我的同事們會把我送到瘋人院。 –