本文介绍了Java 1.4同步:只允许一个方法实例运行(非阻塞)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个提出翻译实用程序的课程。翻译本身应每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同步:只允许一个方法实例运行(非阻塞)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-20 04:10