我需要创建一个包含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);
}
}
}
答案 0 :(得分: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);
}
}
只有当所需的所有服务都在运行时,才会启动服务。现在,您需要迭代所有服务,直到它们全部运行(或者您发现死锁)。
停止服务是相反的问题。您可以在开始时从前任列表中计算后续列表。在后续列表中使用相同的算法。
答案 1 :(得分:0)
尝试搜索“依赖性解析算法”。这篇文章有一个javascript示例:http://www.electricmonk.nl/log/2008/08/07/dependency-resolving-algorithm/