当前位置: 首页 > 面试题库 >

Java 1.4同步:仅允许方法的一个实例运行(非阻塞)?

束研
2023-03-14
问题内容

我有一堂课提议翻译实用程序。翻译本身应每30分钟重新加载一次。我为此使用Spring Timer支持。基本上,我的课看起来像:

public interface Translator {
    public void loadTranslations();
    public String getTranslation(String key);
}

loadTranslations()可能需要很长时间才能运行,因此在运行时,仍然可以使用旧的翻译。这是通过将翻译加载到本地地图中并在加载所有翻译后更改参考来完成的。

我的问题是:如何确保当一个线程已经在加载翻译时,第二个线程也尝试运行,它检测到该线程并立即返回,而不启动第二个更新。

同步方法只会使负载排队…我仍在使用Java 1.4,因此没有java.util.concurrent。

谢谢你的帮助 !


问题答案:

使用某种形式的锁定机制仅在尚未执行任务时执行它。获取锁定令牌必须是一个一步的过程。看到:

/**
 * @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();

}

如果任务同时运行,将抛出异常的测试代码:

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();
        }
    }

}


 类似资料:
  • 问题内容: 我在同一文件中有以下程序。我已经同步了run()方法。 输出是 我的问题是,为什么同步方法同时允许“我的线程1”和“我的线程4”线程访问? 问题答案: 方法在实例级别工作。 类的每个实例都有自己的锁。每次输入实例的任何方法都将获取该锁。这样可以防止多个线程 在同一个实例上 调用方法(请注意,这还可以防止在同一个实例上调用 不同的 方法)。 现在,由于您有两个类实例,因此每个实例都有自己

  • 问题内容: 我想使用数据库模型为我的项目控制一些配置设置。例如: 此模型应该只有一个实例: 当然,如果有人不小心创建了一个新实例,那就不是世界末日了。我可以做。但是,是否有一种方法可以将其锁定,从而无法创建多个实例? 鉴于Django从那时起发生了很大变化,是否有解决此问题的标准方法?还是我应该只使用并接受可能重复的内容? 问题答案: 您可以重写方法以控制实例数:

  • 问题内容: 我需要防止用户多次启动我的Java应用程序(WebStart Swing应用程序)。因此,如果应用程序已经在运行,则应该无法再次启动它或显示警告/再次关闭它。 有一些方便的方法可以做到这一点吗?我考虑过要阻止端口或将某物写入文件。但是希望您可以访问某些系统属性或JVM? 顺便说一句 目标平台是带有Java 1.5的Windows XP 问题答案: 我认为您的建议是在启动应用程序时打开端

  • 本文向大家介绍请你说一下阻塞,非阻塞,同步,异步相关面试题,主要包含被问及请你说一下阻塞,非阻塞,同步,异步时的应答技巧和注意事项,需要的朋友参考一下 参考回答: 阻塞和非阻塞:调用者在事件没有发生的时候,一直在等待事件发生,不能去处理别的任务这是阻塞。调用者在事件没有发生的时候,可以去处理别的任务这是非阻塞。 同步和异步:调用者必须循环自去查看事件有没有发生,这种情况是同步。调用者不用自己去查看

  • #include <stdio.h> #include <pthread.h> int a = 0; int b = 0; void *thread1_func(void *p_arg) { while (1) { a++; sleep(1); } } void *thread2_fu

  • 为什么下面的代码不能保证多个线程之间total_home数字的唯一性,即使逻辑处于同步块中。 } } } 这是一个程序示例。试着运行5-10次,你会发现total_home的值并不是每次都是唯一的。