【问题标题】:Create Thread within a thread - good practice? [duplicate]在线程中创建线程 - 好的做法? [复制]
【发布时间】:2014-02-19 14:20:30
【问题描述】:

在线程中启动线程是一种好习惯吗?我到处搜索,但没有找到太多信息。

我有一个 TimerTask,它每天在特定时间获取用户列表。然后我想获取一些关于用户的数据,但这需要用户输入。因为它需要用户输入,所以我不希望我的 TimerTask 线程在用户没有响应的情况下被阻塞。例如,列表中的第一个用户可能在 X 时间内没有响应,我不想等待 X 时间,直到我向第二个用户询问他们的数据,等等。所以在我的 TimerTask 中,我创建并启动了一个新线程来获取数据。这样,在 Y 时间内,如果我收到了一些数据(但不是全部),我仍然可以做其他事情,而不是等待每个数据都完成。

执行上述操作是一种好习惯吗?有没有更好的解决方案?

这里有一些伪代码,可以帮助你理解。

class UserThread extends TimerTask {

        @Override
        public void run() {
            log.debug("Get a list of members!");
            List<String> users = userManager.getUsers();
            retrieveInitialData(users);
        }

        public void retrieveInitialData(List<String> users) {
            for(String user : users) {
                new Thread(new GetData(user)).start();
            }
        }

        addToSuccessList(String user) {
            synchronized(successList) {
                successList.add(user);
            }
        }

        addToFailureList(String user) {
            synchronized(failureList) {
                failureList.add(user);
            }
        }

        class GetData extends Thread {

            String userID;

            public GetData(String user) {
            this.userID = user;
            }

            public void run() {
            try {
                dataManager.getData(user);
                addToSuccessList(user);
            } catch(Execption e) {
                addToFailureList(user);
            }

        }

【问题讨论】:

  • 没有错。任何线程都可以启动一个新线程。
  • @BalázsMáriaNémeth 谢谢你,不知何故我错过了!
  • 如果一个线程不能创建另一个线程,什么可以(除了操作系统内核加载器/引导程序)?
  • @MartinJames 我知道一个线程可以创建另一个线程,但我想知道这是否是好的做法,或者是否有更好的解决方案。

标签: java multithreading


【解决方案1】:

更好的方法是使用ThreadPoolScheduledExecutorService。从一个线程启动一个线程本身并不是坏事(毕竟所有东西都在一个线程内运行,所以你需要在某个地方这样做!)但可能表明你的设计存在缺陷。

【讨论】:

  • 谢谢蒂姆,我会给 ThreadPool 读一读!
  • ThreadPoolExecutor 解决了与 Thread 不同的问题。 ThreadPoolExecutor 是一个 ExecutorService,它拥有许多线程,并使用它们来执行任务。不同的是,任务的run()方法通常做一件事,然后返回。我们提供给裸线程的 run() 方法通常有一个无限期运行的循环(例如,等待端口上的传入连接,或类似的东西)。
【解决方案2】:

在 Java 中,所有线程都归进程所有,它们从哪里开始并不重要。所以你的代码没有问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-01
    • 2023-02-02
    • 2011-12-06
    • 1970-01-01
    • 2015-06-07
    • 2020-03-15
    • 2013-03-13
    • 1970-01-01
    相关资源
    最近更新 更多