创建Thread对象是否昂贵,或者实际启动线程是否昂贵?

9 浏览
0 Comments

创建Thread对象是否昂贵,或者实际启动线程是否昂贵?

考虑一下这个问题。创建线程被认为是昂贵的,原因有很多,尤其是需要分配大量内存并注册线程。

现在考虑以下代码:

Thread thread = new Thread(new SomeRunnable());

thread.start();

其中哪部分是“昂贵”的部分?是实际创建Thread对象的那一行,还是启动线程的那一行?还是两者都是?我之所以问这个问题是因为我正在编写游戏的服务器组件,我正在考虑是在玩家连接后立即创建Thread对象,并在玩家完成登录后启动线程,还是在玩家完成登录后同时创建和启动线程。

0
0 Comments

创建Thread对象是非常便宜的。你只需要付出调用构造函数的代价。而调用start()方法会占用空间(本地调用,堆栈内存等)。

另一方面,如果你创建了大量的线程,考虑预先创建(并启动)线程池。这已经为你做好了,可以查看Executors类。

非常赞同这个答案-不要显式管理线程,让执行者框架来为你管理。

如果我在玩家连接时创建一个线程,并在玩家断开连接时停止(中断)它,你建议我使用哪个Executor?并且,当你说“你只需要付出调用构造函数的代价。”时,你是否意味着前一行比后一行更昂贵?

:可以查看Executors.newCachedThreadPool()。调用构造函数应该非常快,几乎没有代价。而start()方法需要时间并消耗内存。

0
0 Comments

这个问题的出现原因是作者对性能进行了过早的优化。作者认为在实例化或启动线程的时间点上进行微调不会产生任何差异。但如果有100个线程,作者可能会有不同的看法。如果应用程序存在性能问题,作者建议使用性能分析器来发现真正的性能瓶颈。

解决方法是使用性能分析器来确定应用程序的性能问题,并找出解决方法。作者希望了解两个选项中更好的选择,即实例化线程对象或实际启动线程。

以下是文章的整理内容:

这个问题的出现原因是作者对性能进行了过早的优化。作者认为在实例化或启动线程的时间点上进行微调不会产生任何差异。但如果有100个线程,作者可能会有不同的看法。如果应用程序存在性能问题,作者建议使用性能分析器来发现真正的性能瓶颈。

解决方法是使用性能分析器来确定应用程序的性能问题,并找出解决方法。作者希望了解两个选项中更好的选择,即实例化线程对象或实际启动线程。

0
0 Comments

创建线程对象和启动线程的开销都是昂贵的,这是因为每个线程都需要分配内存和其他资源。为了避免这种开销,可以使用线程池。线程池类似于连接池,它可以避免重复创建线程,并且可以控制线程数量,防止线程数量无限增长。

使用线程池可以提高程序的性能和效率。线程池中的线程可以重复使用,而不是每次需要执行任务时都创建新的线程。这样可以减少线程创建的开销,提高系统的响应速度。

下面是使用Java的线程池的示例代码:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
    public static void main(String[] args) {
        // 创建一个具有固定线程数量的线程池
        ExecutorService executor = Executors.newFixedThreadPool(5);
        // 提交任务给线程池执行
        for (int i = 0; i < 10; i++) {
            Runnable worker = new WorkerThread("" + i);
            executor.execute(worker);
        }
        // 关闭线程池
        executor.shutdown();
        while (!executor.isTerminated()) {
        }
        System.out.println("Finished all threads");
    }
}
class WorkerThread implements Runnable {
    private String message;
    public WorkerThread(String message) {
        this.message = message;
    }
    public void run() {
        System.out.println(Thread.currentThread().getName() + " (Start) message = " + message);
        processMessage();
        System.out.println(Thread.currentThread().getName() + " (End)");
    }
    private void processMessage() {
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在上面的示例中,我们创建了一个固定大小为5的线程池,并提交了10个任务给线程池执行。每个任务都是一个实现了Runnable接口的WorkerThread对象。线程池会自动分配线程来执行这些任务,并在任务完成后回收线程。

通过使用线程池,我们可以避免重复创建线程的开销,提高了程序的效率。同时,线程池还可以控制线程数量,避免线程数量无限增长,保证系统的稳定性。

总之,为了避免线程创建和启动的开销,可以使用线程池来管理线程。这样可以提高程序的性能和效率,并且可以控制线程数量,确保系统的稳定性。

0