I used to work on an app with long running threads. We do this at shutdown,
BlockingQueue<Runnable> queue = threadPool.getQueue();
List<Runnable> list = new ArrayList<Runnable>();
int tasks = queue.drainTo(list);
The list is saved to a file. On startup, the list is added back to the pool so we don’t lose any jobs.