Я бы сделал подкласс ThreadPoolExecutor.
Когда вы устанавливаете ThreadPoolExecutor, вы хотите установить corePoolSize
и maximumPoolSize
на Runtime.getRuntime().availableProcessors()
(посмотрите на Executors.newFixedThreadPool()
, чтобы понять, почему это работает).
Далее вы хотите убедиться, что ваш Queue
также реализует Deque
. LinkedBlockingDeque
является примером, но вы должны присмотреться к нему, чтобы посмотреть, какой из них будет работать лучше для вас. Deque
позволяет вам получить стек, подобный поведению LIFO, и это именно то, что вам нужно.
Поскольку все (submit()
, invokeAll()
) проходит через execute()
, вы захотите переопределить этот метод. В основном делайте то, что вы описали выше:
Проверьте, все ли потоки запущены. Если нет, просто запустите новый runnable в доступном потоке. Если все потоки уже запущены, вам нужно найти тот, на котором выполняется самый старый исполняемый объект, остановить его, повторно поместить в очередь где-нибудь (возможно, в начале?), А затем запустить новый работающий.