Без внешнего ключа, как Вы говорите, что две записи в различных таблицах связаны?
я думаю, к чему Вы обращаетесь, ссылочная целостность, где дочерней записи не позволяют быть созданной без существующей родительской записи и т.д. Они часто известны как ограничения внешнего ключа - но не должны быть перепутаны с существованием внешних ключей во-первых.
Это правда, рассматриваемые классы JDK, похоже, не дают явной гарантии поточно-безопасного представления задачи. Однако на практике все реализации ExecutorService в библиотеке действительно являются потокобезопасными в этом смысле. Я считаю разумным полагаться на это. Поскольку весь код, реализующий эти функции, был размещен в открытом доступе, у кого-либо нет абсолютно никакой мотивации полностью переписывать его другим способом.
Ваш вопрос довольно открытый: все, что делает интерфейс ExecutorService
, - это гарантия того, что какой-то поток где-то обработает отправленный Runnable
или Вызываемый экземпляр
.
Если отправленный Runnable
/ Callable
ссылается на общую структуру данных, доступную из других Runnable
/ Callable
экземпляров (потенциально обрабатываются одновременно разными потоками), то ваша ответственность обеспечить безопасность потоков в этой структуре данных.
Чтобы ответить на вторую часть вашего вопроса, да, у вас будет доступ к ThreadPoolExecutor перед отправкой любые задачи; например
BlockingQueue<Runnable> workQ = new LinkedBlockingQueue<Runnable>();
ExecutorService execService = new ThreadPoolExecutor(4, 4, 0L, TimeUnit.SECONDS, workQ);
...
execService.submit(new Callable(...));
РЕДАКТИРОВАТЬ
На основе комментария Брайана и в случае I ' Я неправильно понял ваш вопрос: отправка задач из нескольких потоков-производителей в ExecutorService
обычно будет потокобезопасной (несмотря на то, что не упоминается явно в API интерфейса, насколько я могу судить). Любая реализация, которая не обеспечивала безопасность потоков, была бы бесполезной в многопоточной среде (поскольку несколько производителей / несколько потребителей - довольно распространенная парадигма), и это именно то, что ExecutorService
(и остальная часть java.util.concurrent
) был разработан для.
Для ThreadPoolExecutor
ответ будет просто да . ExecutorService
не предписывает или иным образом гарантирует, что все реализации являются потокобезопасными, и не может, поскольку это интерфейс. Эти типы контрактов выходят за рамки интерфейса Java. Однако ThreadPoolExecutor
четко задокументирован как потокобезопасный. Более того, ThreadPoolExecutor
управляет своей очередью заданий, используя java.util.concurrent.BlockingQueue
, который является интерфейсом, который требует, чтобы все реализации были потокобезопасными. Любую java.util.concurrent. *
реализацию BlockingQueue
можно смело считать поточно-ориентированной. Любая нестандартная реализация может этого не делать, хотя было бы совершенно глупо, если бы кто-то предоставил очередь реализации BlockingQueue
, которая не была потокобезопасной.
Итак, ответ на ваш заглавный вопрос однозначно да . Ответ на последующий основной вопрос вашего вопроса - , вероятно, , поскольку между ними есть некоторые расхождения.