如何通过实现 Runnable 接口减少内存消耗?

在实现 Runnable 的类中,为了创建线程,我们正在实例化 Thread 类并通过传递 Runnable 对象来调用声明方法。为了创建两个线程,我们创建了两个 Thread 对象和 Runnable 对象。但是在类扩展 Thread 类的情况下,我们只为扩展 Thread 类的类创建两个对象。


class ImplementsRunnable implements Runnable {



 private int counter = 0;


 public void run() {

 counter++;

 System.out.println("ImplementsRunnable : Counter : " + counter);

 }

 }


 class ExtendsThread extends Thread {


 private int counter = 0;


 public void run() {

 counter++;

 System.out.println("ExtendsThread : Counter : " + counter);

 }

 }


 public class ThreadVsRunnable {


 public static void main(String args[]) throws Exception {

 //Multiple threads share the same object.

 ImplementsRunnable rc = new ImplementsRunnable();

 Thread t1 = new Thread(rc);

 t1.start();

 Thread.sleep(1000); // Waiting for 1 second before starting next thread

 Thread t2 = new Thread(rc);

 t2.start();

 Thread.sleep(1000); // Waiting for 1 second before starting next thread

 Thread t3 = new Thread(rc);

 t3.start();


 //Creating new instance for every thread access.

 ExtendsThread tc1 = new ExtendsThread();

 tc1.start();

 Thread.sleep(1000); // Waiting for 1 second before starting next thread

 ExtendsThread tc2 = new ExtendsThread();

 tc2.start();

 Thread.sleep(1000); // Waiting for 1 second before starting next thread

 ExtendsThread tc3 = new ExtendsThread();

 tc3.start();

 }

 }


沧海一幻觉
浏览 164回答 2
2回答

HUH函数

注意:实例化一个Thread对象比实例化一个Runnable实例成本更高(资源方面)。实现Runnable过度扩展背后的想法Thread是线程重用。从概念上讲,一个线程对象可以(同步)运行任意数量的任务(runanbles 就是这种情况)。例如,执行者会利用这一点。Executor executor = Executors.newFixedThreadPool(10);for(int i = 0; i < 1000; i ++ ) {&nbsp; &nbsp; &nbsp;executor.execute(() -> System.out.println("test"));}在这种情况下,10 个线程池运行 1000 个 runanble。与扩展相关的开销会Thread增加您必须处理的任务越多(因此,尽管在您的示例中差异很小,但如果您必须运行 10000 个任务,差异将变得明显)。因此,实施Runnable而不是扩展是一个很好的做法Thread。

慕尼黑5688855

当你构造一个Thread对象时,你所做的不仅仅是构造那个对象。您还可以在 JVM 中分配一个线程,它通常使用操作系统 API 来执行此操作。操作系统线程比进程便宜,但比大多数其他操作系统对象要重要得多,因为每个线程都有自己的执行上下文,需要由内核处理。此外,每个线程都有自己的执行堆栈,必须为此分配空间。在大多数 Java 实现中,与新线程相关的实际内存分配超过 1 兆字节(!)。相比之下,您Runnable只会分配几个字节。如果您在应用程序的整个生命周期中重复使用线程来完成工作,那么内存成本将被摊销。更重要的是,设置新线程的 CPU 时间成本非零(通常是系统调用,这意味着至少进行一次上下文切换,有时会丢失当前线程的其余部分)。与创建新线程相比,将新工作与已经运行的线程进行通信的工作量要少得多。一个好的经验法则是想暴露并发相关机制java.lang(Thread,Object.wait)作为低级别的基本操作,并在暴露的API&nbsp;java.util.concurrent(Executor,Future,等)作为更高级别的操作。低级机制(稍微)更灵活,但也更难正确使用。高级机制同样强大,但通常允许您在更高的抽象层次上思考问题,这通常会使您的程序更清晰、更正确。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java