我知道有关重复使用原型bean的问题被多次询问,但我的问题意味着更多。
有什么问题:
我在for-lookup中的handler(prototype bean)中启动异步任务。但是我无法在上一次达到某个里程碑之前启动下一个异步任务。因此,只有在上一个任务调用特殊方法后才能进行循环。
问题:
@Service(value = "Request.Start")
@Scope("prototype")
public static class Start {
public Start() {}
private Object lock;
@Transactional
public void handler(Request request, Response response) {
for (int i = 0; i < request.getAmount(); i++) {
Utils.asyncProcessStart(); //Can't start the next async process before the previous rich some defined milestone
lock.wait();
}
}
public void proceedLookUp() {
lock.notify();
}
}
@Service
public void AsynchronousTask {
public void asyncAction() [
//Needed logic, before start the next async task
getStartHandler().proceedLookUp();
}
public void getStartHandler() {
//HOW TO REWRITE NEEDED PROTOTYPE BEAN
}
}
此外:
有什么问题 :我使用Activiti框架,这意味着一些限制。我应该将一些变量存储到进程(线程)上下文中。我可以将变量写入全局上下文,但是在进程(线程)启动之前不能写入本地进程(线程)上下文。
你期望发生什么,比如request.getAmount()是否返回2?
我应该在两个不同的线程中启动两个异步进程。每个流程都有相同的变量集。我必须将适当的变量写入每个进程(线程)的本地上下文。但是,我不能在流程(线程)启动之前执行(由于Activiti框架的特定)。
例如,每个进程(线程)都应将“id”属性写入其自己的本地上下文。我在处理程序方法
中有 List ids所以,我应该采取下一步行动:
为什么你不能同步调用它?
正如您已经了解的那样,在第二个进程(线程)的for循环覆盖它之前,不能保证第一个进程(线程)将“id”属性写入它的本地上下文。 / p>
答案 0 :(得分:4)
这是我的建议:创建一个单例对象,您可以在线程之间共享以传递信息(状态)。单例使用semaphore来协调线程。您可以使用此方法将新线程的标识传递回Service类。这是一个简单的例子,展示了我的建议。
测试类:
公共类TestSemaphore {
@Test
public void test() throws Exception {
ThreadCoordinator tc = ThreadCoordinator.getInstance();
for( int i = 0; i < 100; i++ ) {
MyThread r = new MyThread();
r.run();
// This will block until the Thread has called release (after setting its identity on the ThreadCoordinator)
tc.acquire();
String newThreadIdentity = tc.getIdentity();
System.out.println( "Received the new thread's identity: " + newThreadIdentity );
// This will allow the next Thread to acquire the semaphore
tc.release();
}
}
class MyThread extends Thread {
public void run() {
String identity = Integer.toString( (int)(Math.random() * 10000) );
System.out.println( "Running a new thread with identity: " + identity );
// Get a reference to the singleton
ThreadCoordinator tc = ThreadCoordinator.getInstance();
try {
tc.acquire();
tc.setIdentity( identity );
System.out.println( "Notified the ThreadCoordinator from thread: " + identity );
tc.release();
} catch( InterruptedException e ) {
System.out.println( "Caught an interrupted exception: " + e );
}
}
}
}
ThreadCoordinator(信号量)类:
import java.util.concurrent.Semaphore;
public class ThreadCoordinator {
private static ThreadCoordinator tc = new ThreadCoordinator();
private static Semaphore semaphore = new Semaphore( 1, true );
private static String identity;
// singleton get instance
public static ThreadCoordinator getInstance() {
return ThreadCoordinator.tc;
}
public void setIdentity( String identity ) throws InterruptedException {
ThreadCoordinator.identity = identity;
}
public String getIdentity() throws InterruptedException {
String identity = ThreadCoordinator.identity;
ThreadCoordinator.identity = null;
return identity;
}
public void acquire() throws InterruptedException {
ThreadCoordinator.semaphore.acquire();
}
public void release() {
ThreadCoordinator.semaphore.release();
}
}