我知道如何使用 AspectJ 做到这一点。我在下面概述的解决方案将允许您暂停/恢复另一个线程。在您调用暂停例程后,此暂停只会在目标方法内部的下一个方法调用时生效。这将不要求在目标方法的每一行代码之后进行布尔检查。我正在使用等待/通知来执行此操作。
我在下面的例子中使用了 Spring。
首先,将目标方法包装在 Runnable 中。
package com.app.inter.thread.communication.runnables;
public class TestRunnable implements Runnable{
public void run() {
long i=0;
//For explanatory purposes, I have used an infinite loop below
//and printed an increasing number
while(!Thread.interrupted()){
//someService.action1();
//someService.action2();
//....
if(i++%10000000==0)
System.out.println("Working "+i);
}
}
}
接下来,您创建一个切面,该切面将在目标方法中的任何方法调用时被有条件地调用。
@Aspect
@Component
public class HandlerAspect {
public static volatile boolean stop=false;
public static volatile String monitor="";
@Pointcut("withincode(public void com.app.inter.thread.communication.runnables.TestRunnable.run()) "
+ "&& call(* *.*(*)) "
+ "&& if()")
public static boolean stopAspect(){
return stop;
}
@Before("stopAspect()")
public void beforeAdvice(JoinPoint jp) {
try {
System.out.println("Waiting");
synchronized(monitor){
monitor.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
stop=false;
}
}
现在,只要您想暂停线程,只需将 stop 的值设置为 true,反之亦然。
@Service
public class Driver {
@Autowired
private HandlerAspect aspect;
@PostConstruct
public void init(){
Scanner scanner = new Scanner(System.in);
int i=-1;
TestRunnable runnable = new TestRunnable();
Thread thread= new Thread(runnable);
thread.start();
aspect.monitor="MONITOR";
while((i=scanner.nextInt())!=0){
switch(i){
case 1:
aspect.stop=true;
break;
case 2:
aspect.stop=false;
synchronized(aspect.monitor){
aspect.monitor.notify();
}
break;
}
}
// in case the main thread is stopped
// while the other thread is in wait state
synchronized(aspect.monitor){
aspect.monitor.notify();
}
thread.interrupt();
}
}
输出如下:
...
Working 400000001
1Working 410000001
Working 420000001
Working 430000001
Working 440000001
Working 450000001
Working 460000001
Working 470000001
Waiting
2
Working 480000001
Working 490000001
0
工作代码在https://github.com/zafar142007/InterThreadCommunication