mirror of
https://github.com/Winds-Studio/Leaf.git
synced 2025-12-23 00:49:31 +00:00
shutdown mob spawning thread on exit
This commit is contained in:
@@ -1,74 +1,59 @@
|
||||
package gg.pufferfish.pufferfish.util;
|
||||
|
||||
import com.google.common.collect.Queues;
|
||||
import it.unimi.dsi.fastutil.PriorityQueue;
|
||||
import it.unimi.dsi.fastutil.PriorityQueues;
|
||||
import it.unimi.dsi.fastutil.objects.ObjectArrayFIFOQueue;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.locks.Condition;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
import java.util.NoSuchElementException;
|
||||
import java.util.concurrent.locks.LockSupport;
|
||||
|
||||
public class AsyncExecutor implements Runnable {
|
||||
|
||||
private final Logger LOGGER = LogManager.getLogger("Leaf");
|
||||
private final Queue<Runnable> jobs = Queues.newArrayDeque();
|
||||
private final Lock mutex = new ReentrantLock();
|
||||
private final Condition cond = mutex.newCondition();
|
||||
private final PriorityQueue<Runnable> jobs = PriorityQueues.synchronize(new ObjectArrayFIFOQueue<>());
|
||||
private final Thread thread;
|
||||
private volatile boolean killswitch = false;
|
||||
|
||||
public AsyncExecutor(String threadName) {
|
||||
this.thread = new Thread(this, threadName);
|
||||
this.thread = Thread.ofPlatform()
|
||||
.name(threadName)
|
||||
.priority(Thread.NORM_PRIORITY - 1)
|
||||
.daemon(false)
|
||||
.unstarted(this);
|
||||
}
|
||||
|
||||
public void start() {
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
public void kill() throws InterruptedException {
|
||||
killswitch = true;
|
||||
cond.signalAll();
|
||||
LockSupport.unpark(thread);
|
||||
thread.join();
|
||||
}
|
||||
|
||||
public void submit(Runnable runnable) {
|
||||
mutex.lock();
|
||||
try {
|
||||
jobs.offer(runnable);
|
||||
cond.signalAll();
|
||||
} finally {
|
||||
mutex.unlock();
|
||||
}
|
||||
jobs.enqueue(runnable);
|
||||
LockSupport.unpark(thread);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
while (!killswitch) {
|
||||
try {
|
||||
Runnable runnable = takeRunnable();
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
Runnable runnable;
|
||||
try {
|
||||
runnable = jobs.dequeue();
|
||||
} catch (NoSuchElementException e) {
|
||||
LockSupport.park();
|
||||
continue;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
runnable.run();
|
||||
} catch (Exception e) {
|
||||
LOGGER.error("Failed to execute async job for thread {}", thread.getName(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Runnable takeRunnable() throws InterruptedException {
|
||||
mutex.lock();
|
||||
try {
|
||||
while (jobs.isEmpty() && !killswitch) {
|
||||
cond.await();
|
||||
}
|
||||
|
||||
if (jobs.isEmpty()) return null; // We've set killswitch
|
||||
|
||||
return jobs.remove();
|
||||
} finally {
|
||||
mutex.unlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user