首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带执行器和不带执行器多线程的区别

带执行器和不带执行器多线程的区别
EN

Stack Overflow用户
提问于 2012-03-07 07:25:09
回答 1查看 5.4K关注 0票数 2

我试图找出使用executor (用于维护线程池)的普通多线程和多线程之间的性能差异。

下面是两者的代码示例。

没有执行程序代码的(带有多线程):

代码语言:javascript
复制
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadMXBean;
import java.util.List;

public class Demo1 {
public static void main(String arg[]) {
    Demo1 demo = new Demo1();
    Thread t5  = new Thread(new Runnable() {
       public void run() {
              int count=0;
              // Thread.State;
              // System.out.println("ClientMsgReceiver started-----");
              Demo1.ChildDemo  obj = new Demo1.ChildDemo();
              while(true) {

                // System.out.println("Threadcount is"+Thread);
                // System.out.println("count is"+(count++));
                Thread t=new Thread(obj);
                t.start();
                ThreadMXBean tb = ManagementFactory.getThreadMXBean();
                List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
                for (MemoryPoolMXBean pool : pools) {
                   MemoryUsage peak = pool.getPeakUsage();
                   System.out.format("Peak %s memory used: %,d%n",
                             pool.getName(), peak.getUsed());
                   System.out.format("Peak %s memory reserved: %,d%n",
                             pool.getName(), peak.getCommitted());
                } 

                System.out.println("Current Thread Count"+ tb.getThreadCount());
                System.out.println("Peak Thread Count"+ tb.getPeakThreadCount());
                System.out.println("Current_Thread_Cpu_Time " 
                         + tb.getCurrentThreadCpuTime());
                System.out.println("Daemon Thread Count" +tb.getDaemonThreadCount());
       }
       // ChatLogin = new ChatLogin();
     }
  });
  t5.start();
}

static class ChildDemo implements Runnable {
   public void run() {
        try {
        //  System.out.println("Thread Started with custom Run method");
            Thread.sleep(100000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        finally {
            System.out.println("A" +Thread.activeCount());
        }
    }
  }
}

带执行器的(多线程):

代码语言:javascript
复制
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadMXBean;
import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Executor_Demo {
public static void main(String arg[]) {
   BlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(10);
   ThreadPoolExecutor executor   = new ThreadPoolExecutor(
          10, 100, 10, TimeUnit.MICROSECONDS, queue);
   Executor_Demo demo = new Executor_Demo();

   executor.execute(new Runnable() {
       public void run() {
          int count=0;
          // System.out.println("ClientMsgReceiver started-----");
          Executor_Demo.Demo demo2 = new Executor_Demo.Demo();
          BlockingQueue<Runnable> queue1 = new ArrayBlockingQueue<Runnable>(1000);
          ThreadPoolExecutor executor1   = new ThreadPoolExecutor(
                  1000, 10000, 10, TimeUnit.MICROSECONDS, queue1);

          while(true) {
             // System.out.println("Threadcount is"+Thread);
             // System.out.println("count is"+(count++));
             Runnable command= new Demo();
             // executor1.execute(command);
             executor1.submit(command);         
             // Thread t=new Thread(demo2);
             // t.start();
             ThreadMXBean tb = ManagementFactory.getThreadMXBean();
             /* try {
                  executor1.awaitTermination(100, TimeUnit.MICROSECONDS);
                } catch (InterruptedException e) {
                   // TODO Auto-generated catch block
                   e.printStackTrace();
                } */
              List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();
              for (MemoryPoolMXBean pool : pools) {
                 MemoryUsage peak = pool.getPeakUsage();
                 System.out.format("Peak %s memory used: %,d%n",
                          pool.getName(), peak.getUsed());
                 System.out.format("Peak %s memory reserved: %,d%n",
                          pool.getName(), peak.getCommitted());
          }
              System.out.println("daemon threads"+tb.getDaemonThreadCount());
              System.out.println("All threads"+tb.getAllThreadIds());
              System.out.println("current thread CPU time "
                       + tb.getCurrentThreadCpuTime());
              System.out.println("current thread user time "
                       + tb.getCurrentThreadUserTime());
              System.out.println("Total started thread count " 
                       + tb.getTotalStartedThreadCount());
              System.out.println("Current Thread Count"+ tb.getThreadCount());
              System.out.println("Peak Thread Count"+ tb.getPeakThreadCount());
              System.out.println("Current_Thread_Cpu_Time " 
                       + tb.getCurrentThreadCpuTime());
              System.out.println("Daemon Thread Count"
                       + tb.getDaemonThreadCount());
              // executor1.shutdown();  
            }
            //ChatLogin = new ChatLogin();
          }
     });
     executor.shutdown();
}

static class Demo implements Runnable {
    public void run() {
      try {
        // System.out.println("Thread Started with custom Run method");
        Thread.sleep(100000);
      } catch (InterruptedException e) {
          // TODO Auto-generated catch block
          e.printStackTrace();
      }
      finally {
         System.out.println("A" +Thread.activeCount());
      }
   }
  }
}

样本输出

当我运行这两个程序时,结果显示执行器比正常的多线程更昂贵。为什么会这样?

既然如此,遗嘱执行人到底有什么用?我们使用执行器来管理线程池。

我原以为执行者会给出比正常多线程更好的结果。

基本上,我是这样做的,因为我需要使用套接字编程和多线程处理数百万客户端。

任何建议都会有帮助。

EN

回答 1

Stack Overflow用户

发布于 2012-03-07 08:46:02

每个线程消耗堆栈的内存,从256 K到1M不等。您可以手动设置堆栈大小,但将其设置在128 K以下是危险的。因此,如果您有2G内存,并且可以在线程上花费1/2,那么您的线程就不会超过8K。如果这对您来说没有问题,那么使用普通的多线程处理(每个Runnable都有自己的堆栈)。如果您不愿意或不能为每个可运行程序花费这么多内存,请使用执行器。将线程池大小设置为处理器的数量(Runtime.availableProcessors()),或者更多。出现的主要问题是,您无法使Thread.sleep()或在您的运行中阻塞线程(例如,等待用户响应),因为这种阻塞实际上将线程排除在服务之外。因此,如果使用有限大小的线程池,就会出现所谓的“线程饥饿”,这实际上是一个死锁。如果线程池的大小是无限的,那么就会回到正常的多线程处理,很快就会耗尽内存。

解决方法是使用异步操作,即用回调设置一些请求,然后退出run()方法。然后,回调应该使用Executor.execute( Runnable )开始执行某个Runnable对象(可能是相同的),或者它可以执行runnable.run()本身的方法。

现在Java7 (nio2)中存在异步输入输出操作,但我未能使它服务于数百个网络连接。为了服务网络连接,可以使用异步网络库(例如Apache )。

组织回调和执行运行程序可能需要复杂的同步。为了使生活更容易,考虑使用Actor模型(http://en.wikipedia.org/wiki/Actor_model),其中Actor是一个可运行的运行程序,每次输入消息到达时都执行。存在许多Java库(例如https://github.com/rfqu/df4j)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9597331

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档