Тип учебника по Java Threading - PullRequest
3 голосов
/ 02 марта 2009

Я довольно наивен, когда дело доходит до мира Java Threading and 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 в последовательном порядке?

Ответы [ 4 ]

7 голосов
/ 02 марта 2009

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

Последовательная печать чисел 0-99 не является параллельной проблемой и требует синхронизации нитей во избежание неправильной печати. ​​

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

3 голосов
/ 02 марта 2009

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

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

3 голосов
/ 02 марта 2009

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

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

this.exec = Executors.newSingleThreadExecutor();

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

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

0 голосов
/ 02 марта 2009

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

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

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

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

...