gpt4 book ai didi

java - 创建一个在定时器上运行但可以随时唤醒的java线程

转载 作者:行者123 更新时间:2023-11-30 06:29:56 28 4
gpt4 key购买 nike

我想创建一个定期运行某些东西(可运行的)的类,但可以在需要时将其唤醒。如果我可以封装整个东西,我想公开以下方法:

public class SomeService implements Runnable {


public run() {
// the code to run at every interval
}

public static void start() { }
public static void wakeup() { }
public static void shutdown() { }

}

不知何故,我已经走到这一步了。但我不确定这是否是正确的方法。

public class SomeService implements Runnable {

private static SomeService service;
private static Thread thread;
static {
start();
}

private boolean running = true;

private SomeService() {
}

public void run() {
while (running) {
try {
// do what needs to be done
// perhaps peeking at a blocking queue
// or checking for records in a database
// trying to be independent of the communication
System.out.println("what needs to be done");
// wait for 15 seconds or until notify
synchronized (thread) {
try {
thread.wait(15000);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

private static void start() {
System.out.println("start");
service = new SomeService();
thread = new Thread(service);
thread.setDaemon(true);
thread.start();
}

public static void wakeup() {
synchronized (thread) {
thread.notify();
}
}

public static void shutdown() {
synchronized (thread) {
service.running = false;
thread.interrupt();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("shutdown");
}

public static void main(String[] args) throws IOException {

SomeService.wakeup();
System.in.read();
SomeService.wakeup();
System.in.read();
SomeService.shutdown();

}

}

我担心变量应该声明为 volatile。并且还担心我应该检查 thread.isInterrupted() 的“需要完成的部分”。这看起来是正确的方法吗?我应该把它翻译给执行者吗?如何强制在预定的执行程序上运行?

编辑

经过executor的实验,似乎这种做法似乎是合理的。你怎么看?

public class SomeExecutorService implements Runnable {

private static final SomeExecutorService runner
= new SomeExecutorService();

private static final ScheduledExecutorService executor
= Executors.newSingleThreadScheduledExecutor();

// properties

ScheduledFuture<?> scheduled = null;

// constructors

private SomeExecutorService() {
}

// methods

public void schedule(int seconds) {
scheduled = executor.schedule(runner, seconds, TimeUnit.SECONDS);
}

public void force() {
if (scheduled.cancel(false)) {
schedule(0);
}
}

public void run() {
try {
_logger.trace("doing what is needed");
} catch (Exception e) {
_logger.error("unexpected exception", e);
} finally {
schedule(DELAY_SECONDS);
}
}

// static methods

public static void initialize() {
runner.schedule(0);
}

public static void wakeup() {
runner.force();
}

public static void destroy() {
executor.shutdownNow();
}

}

最佳答案

对于初学者——您可能不想自己实现 Runnable;你应该接受一个Runnable。如果您希望将您的类传递给其他人执行,您应该只实现 Runnable。

为什么不包装一个 ScheduledExecutorService?这是一个快速(非常差,但应该是功能性的)实现。

public class PokeableService {

private ScheduledExecutorService service = Executors.newScheduledThreadPool(1);
private final Runnable codeToRun;

public PokeableService (Runnable toRun, long delay, long interval, TimeUnit units) {
codeToRun = toRun;
service.scheduleAtFixedRate(toRun, delay, interval, units);
}

public void poke () {
service.execute(codeToRun);
}
}

关于java - 创建一个在定时器上运行但可以随时唤醒的java线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11037551/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com