3

当谈到 Java 线程和并发的世界时,我相当天真。我目前正在努力学习。我做了一个简单的例子来试图弄清楚并发是如何工作的。

这是我的代码:

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

4 回答 4

7

线程池通常用于不需要同步或高度并行的操作。

顺序打印数字 0-99 不是并发问题,需要同步线程以避免打印乱序。

我建议看一下Java 并发课程,以了解 Java 中的并发性。

于 2009-03-02T18:14:41.370 回答
3

解决问题的最简单方法是使用大小为 1 的 ThreadPool。但是,这并不是真正使用线程来解决的问题。

要扩展,如果您使用以下命令创建执行程序:

this.exec = Executors.newSingleThreadExecutor();

那么您的线程将全部按照提交执行的顺序进行调度和执行。在少数情况下这是合乎逻辑的事情,但在大多数情况下,线程不是用来解决这个问题的错误工具。

当您需要在不同的线程中执行任务时,这种事情是有意义的——可能需要很长时间才能执行并且您不想阻塞 GUI 线程——但您不需要或不这样做'不希望提交的任务同时运行。

于 2009-03-02T18:16:56.887 回答
3

线程的想法不是按顺序做事。

您将需要一些共享状态来协调。在示例中,将实例字段添加到外部类将在此示例中起作用。从添加中删除参数。添加一个锁对象和一个计数器。抓住锁,增加打印数字,增加数字,释放数字。

于 2009-03-02T18:17:54.250 回答
0

根据定义,该问题不适合线程。线程是独立运行的,实际上并没有办法预测哪个线程首先运行。

如果要更改代码以按顺序运行,请将添加更改为:

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

你没有使用线程(至少不是你自己的),一切都是按顺序发生的。

于 2009-03-02T20:57:20.233 回答