繁体   English   中英

java中的服务(线程)

[英]services (threads) in sequence java

我有一项任务,要互相依靠3(A,B,C)个服务。 服务A启动时,服务B可以启动;服务B启动时,服务C可以启动; C停止时,B可以停止; B停止时,A可以停止。 我设法启动线程并使用状态选项从一个切换到另一个。 我不得不说,我对Java不太了解,但是我刚开始学习Java,所以我在这个方面是新手,所以任何帮助,建议等都很棒。

我也有3个几乎相同的类,所以谁能告诉他们如何用一个替换这3个类? 有什么办法吗?

这是我的代码:

public class service_class {
    int status=1;
    public static void main(String[] args) {

        service_class service_class = new service_class();

        A1 a=new A1(service_class);
        B1 b=new B1(service_class);
        C1 c=new C1(service_class);

        a.start();
        b.start();
        c.start();

    }
}

class A1 extends Thread{
    service_class service_class;

    A1(service_class service_class){
        this.service_class = service_class;
    }


    @Override
    public void run() {

        try{
            synchronized (service_class) {
                 while(service_class.status!=1){
                        service_class.wait();
                    }

                    System.out.print("A started" + "\n");
                    service_class.status = 2;
                    service_class.notifyAll();

                    while(service_class.status!=7){
                        service_class.wait();
                    }
                    System.out.print("A stoped" + "\n");
                    service_class.status = 1;
                    service_class.notifyAll();
                }

        }catch (Exception e) {
            System.out.println("Exception 1 :"+e.getMessage());
        }

    }

}

class B1 extends Thread{

    service_class service_class;

    B1(service_class service_class){
        this.service_class = service_class;
    }

    @Override
    public void run() {

        try{
            synchronized (service_class) {

                    while(service_class.status!=2){
                        service_class.wait();
                    }

                    System.out.print("B started " + "\n");
                    service_class.status = 4;
                    service_class.notifyAll();

                    while(service_class.status!=6){
                        service_class.wait();
                    }
                    System.out.print("B stoped" + "\n");
                    service_class.status = 7;
                    service_class.notifyAll();
                }

        }catch (Exception e) {
            System.out.println("Exception 2 :"+e.getMessage());
        }

    }
}


class C1 extends Thread{

    service_class service_class;

    C1(service_class service_class){
        this.service_class = service_class;
    }

    @Override
    public void run() {

        try{
            synchronized (service_class) {
                 while(service_class.status!=4){
                        service_class.wait();
                    }
                    System.out.print("C started" + "\n");
                    service_class.status = 5;
                    service_class.notifyAll();

                    while(service_class.status!=5){
                        service_class.wait();
                    }
                    System.out.print("C stoped" + "\n");
                    service_class.status = 6;
                    service_class.notifyAll();
            }
        }catch (Exception e) {
            System.out.println("Exception 4 :"+e.getMessage());
        };

    }
}

我有3个几乎相同的类,所以谁能告诉他们如何用一个替换这3个类? 有什么办法吗?

看起来ABC这3个类之间的区别是:

  • 打印的名称字符串,以及
  • 每个人测试和设置的状态值。

因此,只需将它们替换为final实例变量,然后将其初始化为传递给(统一)类构造函数的值即可。


但是...

扩展Thread通常被认为是一个坏主意。 首先,它使使用线程池变得困难。 更好的方法是使用标准的Thread类,并在构造它时将其传递给Runnable实例。 实际上,如果您正在使用线程池或Executor服务或其他服务,则甚至不需要自己创建和管理线程。

至于wait / notify东西,使用更高级别的同步结构(例如CountDownLatch )更容易。

使用CountDownLatch

CountDownLatch用给定的计数初始化。 由于调用countDown()方法(由其他线程)导致计数达到零,然后await方法阻塞,然后释放所有等待线程。 我的建议是编写一个超类:

  • 提供初始计数为1的锁存器
  • 接受该类的另一个实例或在执行之前要等待的CountDownLatch
  • 减少启动时的闩锁
  • run包装该逻辑,并提供抽象方法innerRun ,将在其中实现实际代码。

     abstract class LatchedRunnable extends Runnable { private CountDownLatch latch=new CountDownLatch(1); private CountDownLatch wait; public Foo(LatchedRunnable waitFor) { this.wait=waitFor.latch; } public Foo(CountDownLatch waitFor) { this.wait=waitFor; } final run () { //wait for the other thread if (wait!=null) try {wait.await();} catch (InterruptedException e) {return;} //signal that we have started latch.countDown(); //actually start innerRun(); } protected abstract void innerRun(); //do stuff here } class Foo extends LatchedRunnable { Foo(LatchedRunnable waitFor) {super(waitFor);} protected void innerRun() {...} } class Bar extends LatchedRunnable { Bar(LatchedRunnable waitFor) {super(waitFor);} protected void innerRun() {...} } Foo foo = new Foo(null); Bar bar = new Bar(foo); 

以我的理解,CountDownLatch是一种在不进入死锁的情况下实现同步的机制。 所以就这样,

考虑一下,Thread1执行一项任务,例如读取文件。 读取完整文件后,另一个线程可以处理文件内容并获取某些信息。 现在,第三个线程负责将信息复制到数据库。

假设有多个客户端使用上述相同步骤并以相同顺序进行:

  1. FILEREAD
  2. FileProcessor
  3. 的dbupdate

与创建顺序不同的是,我们创建了三个线程池。

ThreadPool<FileReaderThread> poolA;
ThreadPool<FileProcessorThread> poolB;
ThreadPool<DBUpdate> poolC;

随着新请求的到来,将创建具有适当计数的倒计时锁。 当poolA中的线程完成其工作时,计数将减少。 一旦该计数达到0,将调用poolB中的线程。类似地,另一个countdownlatch将用于同步poolB和poolC中的线程。 理想情况下,我们使用CountDownLatch实现顺序过程。

如果有错误,请更正。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM