我的任务是相互依赖3(A,B,C)服务。当服务A启动时,服务B可以启动,当服务B启动时,服务C可以启动,当C停止时,B可以停止,当B停止时A可以停止。 我已经设法启动线程并使用status选项从一个切换到另一个。我不得不说,我不知道关于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());
};
}
}
答案 0 :(得分:3)
我有3个几乎相同的类,所以任何人都可以告诉他们如何用一个替换这3个类?有什么办法吗?
看来3个类A
,B
和C
之间的差异是:
所以只需用final
个实例变量替换它们,并用传递给(统一)类构造函数的值初始化它们。
然而......
通常认为扩展Thread
是一个坏主意。首先,它使得难以使用线程池。更好的方法是使用标准Thread
类,并在构造它时将其传递给Runnable
实例。实际上,如果您正在使用线程池或Executor服务或其他任何东西,您甚至不需要自己创建和管理线程。
对于等待/通知内容,使用更高级别的同步构造(例如CountDownLatch
)更容易。
答案 1 :(得分:1)
使用给定计数初始化CountDownLatch
。 await
方法阻塞,直到计数达到零,这是由于countDown()
方法(由其他线程)的调用,之后所有等待的线程都被释放。我的建议是编写一个超类:
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);
答案 2 :(得分:0)
CountDownLatch是一种在不进入死锁的情况下实现同步的机制。所以在这里,
考虑一下,Thread1执行一个文件读取等任务。一旦读取完整文件,另一个线程就可以处理文件内容并获取某些信息。现在第三个线程负责将信息复制到DB。
假设有多个客户端使用上述相同的步骤并且顺序相同:
我们不是按顺序处理所有内容,而是创建三个线程池。
ThreadPool<FileReaderThread> poolA;
ThreadPool<FileProcessorThread> poolB;
ThreadPool<DBUpdate> poolC;
随着新请求的进入,将创建一个具有适当计数的倒计时。当poolA中的线程完成其工作时,计数将递减。一旦此计数达到0,将调用来自poolB的线程。类似地,另一个countdownlatch将用于同步来自poolB和poolC的线程。理想情况下,我们使用CountDownLatch实现顺序过程。
如果出现问题,请更正。