问题描述
我有一个提出翻译实用程序的课程。翻译本身应每30分钟重新加载一次。我使用Spring Timer支持。基本上,我的班级看起来像:
I have a class proposing translations utilities. The translations themselves should be reloaded every 30 minutes. I use Spring Timer support for that. Basically, my class looks like :
public interface Translator {
public void loadTranslations();
public String getTranslation(String key);
}
loadTranslations()运行起来可能很长,所以当它运行时旧的翻译仍然可用。这是通过在本地Map中加载翻译并在加载所有翻译时更改引用来完成的。
loadTranslations() can be pretty long to run, so while it is running the old translations are still available. This is done by loading the translations in a local Map and just changing the reference when all translations are loaded.
我的问题是:如何确保当一个帖子时已经加载了翻译,第二个也尝试运行,它检测到并立即返回,而不开始第二次更新。
My problem is : how do I make sure that when a thread is already loading translations, is a second one also tries to run, it detects that and returns immediately, without starting a second update.
同步方法只会对负载进行排队...我还在Java 1.4上,所以没有java.util.concurrent。
A synchronized method will only queue the loads ... I'm still on Java 1.4, so no java.util.concurrent.
感谢您的帮助!
推荐答案
使用某种形式的锁定机制只执行任务(如果尚未进行)。获取锁定令牌必须是一步到位的过程。请参阅:
Use some form of locking mechanism to only perform the task if it is not already in progress. Acquiring the locking token must be a one-step process. See:
/**
* @author McDowell
*/
public abstract class NonconcurrentTask implements Runnable {
private boolean token = true;
private synchronized boolean acquire() {
boolean ret = token;
token = false;
return ret;
}
private synchronized void release() {
token = true;
}
public final void run() {
if (acquire()) {
try {
doTask();
} finally {
release();
}
}
}
protected abstract void doTask();
}
如果任务同时运行,将抛出异常的测试代码:
Test code that will throw an exception if the task runs concurrently:
public class Test {
public static void main(String[] args) {
final NonconcurrentTask shared = new NonconcurrentTask() {
private boolean working = false;
protected void doTask() {
System.out.println("Working: "
+ Thread.currentThread().getName());
if (working) {
throw new IllegalStateException();
}
working = true;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
if (!working) {
throw new IllegalStateException();
}
working = false;
}
};
Runnable taskWrapper = new Runnable() {
public void run() {
while (true) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
shared.run();
}
}
};
for (int i = 0; i < 100; i++) {
new Thread(taskWrapper).start();
}
}
}
这篇关于Java 1.4同步:只允许一个方法实例运行(非阻塞)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!