3

我需要创建一个包含 4 个服务(例如 A、B、C 和 D)的服务管理器,加载服务列表。服务需要有start()stop()方法,它们按以下顺序相互依赖:

  • 服务 B 和 C 依赖于服务 A

  • 服务 D 依赖于服务 B

并且可以推断出以下内容:

  • 要启动服务D,需要启动服务A和B

  • 要停止服务 A,必须先停止服务 B、D 和 C

  • 服务 B 和 C 可以在 A 启动后立即并行启动。相反,它们可以并行停止。

这是我的代码无法正常工作。问题是它按其顺序启动服务,但只是因为我将它们按列表中的顺序排列。我弄得一团糟。我需要帮助,因为现在我不知道如何使用我评论过的这行代码,也不知道如何阻止它。谢谢你的帮助!

public class CountDown {

    public static void main(String args[]) {

        List<String> Services = Collections.synchronizedList(new ArrayList<String>());
        Services.add("Services A");
        Services.add("Services B");
        Services.add("Services C");
        Services.add("Services D");


       final CountDownLatch Start = new CountDownLatch(4);
       final CountDownLatch Stop = new CountDownLatch(4);

    new Thread(new Service("Service A", 1000, Start, Stop, Services)).start();
    new Thread(new Service("Service B", 2000, Start, Stop, Services)).start();
    new Thread(new Service("Service C", 3000, Start, Stop, Services)).start();
    new Thread(new Service("Service D", 4000, Start, Stop, Services)).start();

    /* A.start(); // this is how it should work

      if (A.isAlive())
      {
          B.start();
          C.start();
      }

      if(B.isAlive() && A.isAlive())
      {
          D.start();
      }

      D.interrupt();
      if(D.isInterrupted())
      {
          B.interrupt();
          C.interrupt();

      }
      if(B.isInterrupted() && D.isInterrupted())
      {
          A.interrupt();
      }*/



      try { 
          Start.await();
          Stop.countDown();   
    } catch(InterruptedException ie){
        ie.printStackTrace();
    }

    }

}



class Service implements Runnable{

    List<String> list;
    private final String name;
    private final int time;
    private final CountDownLatch Stop;
    private final CountDownLatch Start;


    public Service(String name, int time, CountDownLatch Start, CountDownLatch Stop, List<String> list){
        this.name = name;
        this.time = time;
        this.Start = Start;
        this.Stop = Stop;

        this.list = list;
    }

    @Override
    public void run() {


        try {


            Start.countDown();
           Thread.sleep(time);    
            list.add(name);


            System.out.println( name + " is Up!");


           Stop.await();

        } catch (InterruptedException ex) {
            Logger.getLogger(Service.class.getName()).log(Level.SEVERE, null, ex);
        }


    }

}
4

2 回答 2

1

如果你想使它成为一个通用的相互依赖的服务系统,你需要在元数据中捕获关于服务的依赖关系。让我们假设您对每项服务都有以下可用数据:

List<String> getPredecessors();

它返回在此服务启动之前必须运行的所有服务的名称。然后你有一组已经启动的服务:

Set<String> startedServices = new HashSet<String>();

for ( String service: Services ) {
    boolean allClear = true;
    for ( String predecessor: Service(service).getPredecessors() ) {
        if ( ! startedServices.contains(predecessor) ) {
            allClear = false;
            break;
        }
    }
    if ( allClear ) {
        // start the service
        new Thread(new Service(service, 1000, Start, Stop, Services)).start();
        startedServices.add(service);
    }
}

只有当它需要的所有服务都在运行时,这才会启动一个服务。现在您需要遍历所有服务,直到它们全部运行(或者您发现死锁)。

停止服务是相反的问题。您可以在启动时从前任列表中计算后继列表。在后继列表上使用相同的算法。

于 2013-06-11T12:10:17.197 回答
0

尝试搜索“依赖解析算法”。这篇文章在这里有一个javascript示例:http ://www.electricmonk.nl/log/2008/08/07/dependency-resolving-algorithm/

于 2013-06-11T10:49:10.147 回答