我的应用程序有多个线程。如果服务器出现故障或重新启动,我想只执行那些未执行的线程。例如,在下面的代码段中:考虑在执行线程号1,4,2后服务器是否关闭。应用程序应在服务器重新启动后执行2,3和5个线程。
线程的任务本质上是ATOMIC。要么全部完成,要么没有任何反应。所以我必须以某种方式保存已执行的每个线程的状态。我怎么能这样做?
class HugeJob implements Runnable {
int param;
public HugeJob(int var) {
this.param = var;
}
public void run() {
//This is an ATOMIC task i.e. either all gets done or nothing
//Each thread task takes ~20 minute. Heavy I/O and network operations
//I have to make sure no thread executes more than once even if server is restarted
System.out.println(this.param);
}
}
public class ThreadSample {
public static void main(String [] args)
{
for(int i =0; i<5;i++)
{
HugeJob obj = new HugeJob(i);
new Thread(obj).start();
}
}
}
感谢您的帮助。
修改 我可以使用Quartz实现这一目标吗?将每个线程创建为一个单独的工作并使用Quartz保留它是一个好主意吗?以下是相关链接:JavaQuartz Job persistence
答案 0 :(得分:0)
我相信你的要求是不可能的,因为这是拜占庭将军问题的一个变种,这个问题可证明是无法解决的。正在完成的线程类似于攻击的一个将军。确保线程不再运行所需的记录类似于其他一般攻击。因此,你的要求类似于要求两个将军攻击或两者都无法满足的要求。
您无法避免以下基本问题。
线程结束。
您记录线程已完成,以便您不再进行此项工作。
如果系统在1之后但在2之前关闭怎么办?
您需要重新考虑问题和要求。您提出的过于简化的版本无法按要求解决。
答案 1 :(得分:0)
我以一种复杂的方式解决了这个问题
我使用Callable Interface,以便跟踪我的“Thread”
添加ShutdownHook 1
第1部分:创建可调用对象
Set<Future<Boolean>> set = new HashSet<Future<Boolean>>();
public HttpServer server = null; public HttpContext hc = null;
public void myServerInitiator() throws IOException {
server = HttpServer.create(new InetSocketAddress(port), 0);
hc = server.createContext("/test", new MyHandler());
// create all the thread and start it here
for(int i =0; i<5;i++)
Callable<Boolean> callable = new MyDelegator ();
Future<Boolean> future = pool.submit(callable);
set.add(future);
}
........
}
第2部分:添加钩子
public void myServerStop() throws IOException {
Runtime rt = Runtime.getRuntime();
rt.addShutdownHook(new Thread() {
public void run() {
// In real life this might close a Connection or something.
System.out.println("Running shutdown hook and closing all connection");
if(server != null) {
server.removeContext(hc);
server.stop(1);
}
// get all the "thread object" and do whatever you want based on the state
for (Future<Boolean> future : set) {
}
});
}