Вопрос

Я довольно наивен, когда дело касается мира Java Threading и Concurrency.В настоящее время я пытаюсь учиться.Я привел простой пример, чтобы попытаться понять, как работает параллелизм.

Вот мой код:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadedService {

    private ExecutorService exec;

    /**
     * @param delegate
     * @param poolSize
     */
    public ThreadedService(int poolSize) {
        if (poolSize < 1) {
            this.exec = Executors.newCachedThreadPool();
        } else {
            this.exec = Executors.newFixedThreadPool(poolSize);
        }
    }

    public void add(final String str) {
        exec.execute(new Runnable() {
            public void run() {
                System.out.println(str);
            }

        });

    }

    public static void main(String args[]) {
        ThreadedService t = new ThreadedService(25);
        for (int i = 0; i < 100; i++) {
            t.add("ADD: " + i);
        }
    }

}

Что мне нужно сделать, чтобы код выводил числа от 0 до 99 в последовательном порядке?

Это было полезно?

Решение

Пулы потоков обычно используются для операций, которые не требуют синхронизация или очень параллельный.

Последовательная печать чисел 0–99 не является параллельной проблемой и требует синхронизации потоков, чтобы избежать нарушения порядка печати.

Рекомендую взглянуть на Урок Java-параллелизма чтобы получить представление о параллелизме в Java.

Другие советы

Идея потоков заключается не в том, чтобы делать что-то последовательно.

Для координации вам понадобится какое-то общее состояние.В этом примере добавление полей экземпляра во внешний класс будет работать.Удалите параметр из доп.Добавьте объект блокировки и счетчик.Возьмите замок, увеличьте число, напечатайте число, увеличьте число, отпустите число.

Самое простое решение вашей проблемы — использовать размер ThreadPool, равный 1.Однако на самом деле это не та проблема, для решения которой можно было бы использовать потоки.

Чтобы расширить, если вы создадите своего исполнителя с помощью:

this.exec = Executors.newSingleThreadExecutor();

тогда все ваши потоки будут запланированы и выполнены в том порядке, в котором они были отправлены на выполнение.Есть несколько сценариев, в которых это логично, но в большинстве случаев потоки — неправильный инструмент для решения этой проблемы.

Подобные вещи имеет смысл делать, когда вам нужно выполнить задачу в другом потоке — возможно, это занимает много времени, и вы не хотите блокировать поток графического интерфейса — но вам это не нужно или не нужно Я не хочу, чтобы отправленные задачи выполнялись одновременно.

Проблема по определению не подходит для потоков.Потоки запускаются независимо, и на самом деле не существует способа предсказать, какой поток запустится первым.

Если вы хотите изменить свой код для последовательного запуска, измените add на:

public void add(final String str) {
    System.out.println(str);
}

Вы не используете потоки (по крайней мере, свои), и все происходит последовательно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top