Потокобезопасность, если цикл является потокобезопасным

Цикл while в этом вопросе является потокобезопасным: безопасность потоков AtomicInteger. Если я вставлю метод randomSum в потокобезопасный цикл while, будет ли код по-прежнему потокобезопасным? Или метод randomSum должен быть синхронизирован?

import java.util.ArrayList;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;

public class Print implements Runnable {
    static AtomicInteger atomicInteger = new AtomicInteger(0);
    static Random random = new Random(1);

    public static int randomSum() {
        int sum = 0;
        for (int i = 0; i < 10; i++) {
            sum += random.nextInt();
        }
        return sum;
    }

    @Override
    public void run() {
        while (atomicInteger.getAndIncrement() < 100)
            System.out.println(randomSum() + " " + Thread.currentThread());
    }

    public static void main(String[] args) throws InterruptedException {
        ArrayList<Thread> threads = new ArrayList<>();

        for (int i = 0; i < 5; i++)
            threads.add(new Thread(new Print()));

        for (Thread thread : threads)
            thread.start();

        for (Thread thread : threads)
            thread.join();
    }
}

person Anne Maier    schedule 09.06.2021    source источник
comment
Да, все еще потокобезопасный. Нет необходимости синхронизировать этот метод randomSum, так как вы не изменяли никаких значений вне метода.   -  person Sachith Dickwella    schedule 09.06.2021
comment
@Sachith Dickwella Ну, на самом деле random.nextInt изменяет random внутри, но Random является потокобезопасным.   -  person rghome    schedule 09.06.2021
comment
Это не совсем дубликат stackoverflow.com/questions/5819638, но если Random является потокобезопасным, то из этого следует, что ваш randomSum является потокобезопасным, поскольку sum и i являются локальными переменными и, следовательно, привязаны к потоку.   -  person Stephen C    schedule 09.06.2021


Ответы (1)


Метод randomSum является потокобезопасным, как и его использование.

Единственный общий объект — random. В документации API Java указано, что экземпляры java.util.Random являются потокобезопасными, но при одновременном использовании могут возникнуть проблемы с производительностью (предположительно из-за синхронизации) и что ThreadLocalRandom вместо этого следует учитывать, если производительность является проблемой.

person rghome    schedule 09.06.2021