Параллельный доступ к статическим методам

У меня есть статический метод со следующей сигнатурой:

public static List<ResultObjects> processRequest(RequestObject req){
  // process the request object and return the results.
}

Что происходит при одновременном одновременном вызове нескольких вызовов, указанных выше? Будут ли обрабатываться запросы одновременно или один за другим?

Ответ 1

Отвечая именно на ваш вопрос:

  • Метод будет выполняться одновременно (несколько раз в одно и то же время, если у вас несколько потоков).
  • Запросы будут обрабатываться одновременно.

Вам нужно добавить модификатор synchronized, если вы работаете с объектами, которые требуют параллельного доступа.

Ответ 2

Если вам нужно избегать параллельного выполнения, вам необходимо явно синхронизировать. Тот факт, что метод статичен, не имеет к этому никакого отношения. Если вы объявите сам метод synchronized, то синхронизация будет находиться в объекте класса. В противном случае вам нужно будет синхронизировать какой-либо статический объект (поскольку this не существует для статических методов).

Ответ 3

Все вызовы метода будут выполняться одновременно... но:

У вас может возникнуть проблема concurrency (и в ситуации, не зависящей от потока), как только код вашего статического метода изменит статические переменные. И в этом случае вы можете объявить свой метод как synchronized

Если ваш метод использует только локальные переменные, у вас не будет проблем с concurrency.

Ответ 4

Вы можете проверить это самостоятельно:

public class ConcurrentStatic {

    public static void main(String[] args) {
        for (String name: new String[] {"Foo", "Bar", "Baz"}) {
            new Thread(getRunnable(name)).start();
        }
    }

    public static Runnable getRunnable(final String name) {
        return new Runnable() {
            public void run() {
                longTask(name);
            }
        };
    }

    public static void longTask(String label) {
        System.out.println(label + ": start");
        try {
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(label + ": end");
    }

}

Ответ 5

все вызовы методов из отдельных потоков в java по умолчанию совпадают.

Ответ 6

Я вижу много ответов, но ни один из них не указывает на причину.

Так что это можно думать так,
Всякий раз, когда создается поток, он создается со своим собственным стеком (я предполагаю, что размер стека на момент создания составляет ~ 2 МБ). Таким образом, любое выполнение, которое происходит, на самом деле происходит в контексте этого стека потоков.
Любая созданная переменная живет в куче, но ссылается на нее в стеке, за исключением того, что статические переменные не находятся в стеке потока.

Любой вызов функции фактически помещается в стек потоков, будь то статический или нестатический. Поскольку полный метод был помещен в стек, любое создание переменной происходит в стеке (опять же, за исключением статических переменных) и доступно только одному потоку.

Таким образом, все методы являются потокобезопасными, пока они не изменят состояние некоторой статической переменной.