可以在我的杯子里混合牛奶和咖啡

时间:2014-03-04 11:30:31

标签: java multithreading

嗯,好的,

由于观察者模式在这里超重,我自己尝试。

无论如何,咖啡或牛奶都没有放入杯中。

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.

我的问题:为了让我的咖啡混合,我该怎么做?

2 个答案:

答案 0 :(得分:3)

这就是为什么你不能喝早晨咖啡的原因:

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

一项任务只能有一个岗位任务,在你的情况下,杯子需要有2 - 咖啡和牛奶。将postTask转换为postTasks

答案 1 :(得分:1)

请注意,扩展Thread的整个方法都值得怀疑。以下是更推荐的编程风格的示例:

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