下载安卓APP箭头
箭头给我发消息

客服QQ:3315713922

浅析在java中如何检查过多的线程

作者:课课家教育     来源: http://www.kokojia.com点击数:1074发布时间: 2016-02-29 20:02:44

标签: java对象java继承java构建器

大神带你学编程,欢迎选课

  有些时候,我们会发现ColorBoxes几乎陷于停顿状态。在我自己的机器上,这一情况在产生了10×10的网格之后发生了。为什么会这样呢?自然地,我们有理由怀疑AWT对它做了什么事情。所以这里有一个例子能够测试那个猜测,它产生了较少的线程。代码经过了重新组织,使一个Vector实现了Runnable,而且那个Vector容纳了数量众多的色块,并随机挑选一些进行更新。随后,我们创建大量这些Vector对象,数量大致取决于我们挑选的网格维数。结果便是我们得到比色块少得多的线程。所以假如有一个速度的加快,我们就能立即知道,因为前例的线程数量太多了。如下所示:

浅析在java中如何检查过多的线程_java对象_java继承_课课家

  //: ColorBoxes2.java

  // Balancing thread use

  import java.awt.*;

  import java.awt.event.*;

  import java.util.*;

  class CBox2 extends Canvas {

  private static final Color[] colors = {

  Color.black, Color.blue, Color.cyan,

  Color.darkGray, Color.gray, Color.green,

  Color.lightGray, Color.magenta,

  Color.orange, Color.pink, Color.red,

  Color.white, Color.yellow

  };

  private Color cColor = newColor();

  private static final Color newColor() {

  return colors[

  (int)(Math.random() * colors.length)

  ];

  }

  void nextColor() {

  cColor = newColor();

  repaint();

  }

  public void paint(Graphics g) {

  g.setColor(cColor);

  Dimension s = getSize();

  g.fillRect(0, 0, s.width, s.height);

  }

  }

  class CBoxVector

  extends Vector implements Runnable {

  private Thread t;

  private int pause;

  public CBoxVector(int pause) {

  this.pause = pause;

  t = new Thread(this);

  }

  public void go() { t.start(); }

  public void run() {

  while(true) {

  int i = (int)(Math.random() * size());

  ((CBox2)elementAt(i)).nextColor();

  try {

  t.sleep(pause);

  } catch(InterruptedException e) {}

  }

  }

  }

  public class ColorBoxes2 extends Frame {

  private CBoxVector[] v;

  public ColorBoxes2(int pause, int grid) {

  setTitle("ColorBoxes2");

  sETLayout(new GridLayout(grid, grid));

  v = new CBoxVector[grid];

  for(int i = 0; i < grid; i++)

  v[i] = new CBoxVector(pause);

  for (int i = 0; i < grid * grid; i++) {

  v[i % grid].addElement(new CBox2());

  add((CBox2)v[i % grid].lastElement());

  }

  for(int i = 0; i < grid; i++)

  v[i].go();

  addwindowListener(new WindowAdapter() {

  public void windowClosing(WindowEvent e) {

  System.exit(0);

  }

  });

  }

  public static void main(String[] args) {

  // Shorter default pause than ColorBoxes:

  int pause = 5;

  int grid = 8;

  if(args.length > 0)

  pause = Integer.parseInt(args[0]);

  if(args.length > 1)

  grid = Integer.parseInt(args[1]);

  Frame f = new ColorBoxes2(pause, grid);

  f.setSize(500, 400);

  f.setVisible(true);

  }

  } ///:~

  在ColorBoxes2中,我们创建了CBoxVector的一个数组,并对其初始化,使其容下各个CBoxVector网格。每个网格都知道自己该“睡眠”多长的时间。随后为每个CBoxVector都添加等量的Cbox2对象,而且将每个Vector都告诉给go(),用它来启动自己的线程。

  CBox2类似CBox——能用一种随机选择的颜色描绘自己。但那就是CBox2能够做的全部工作。所有涉及线程的处理都已移至CBoxVector进行。

  CBoxVector也可以拥有继承的Thread,并有一个类型为Vector的成员对象。这样设计的好处就是addElement()和elementAt()方法可以获得特定的参数以及返回值类型,而不是只能获得常规Object(它们的名字也可以变得更短)。然而,这里采用的设计表面上看需要较少的代码。除此以外,它会自动保留一个Vector的其他所有行为。由于elementAt()需要大量进行“封闭”工作,用到许多括号,所以随着代码主体的扩充,最终仍有可能需要大量代码。

  和以前一样,在我们实现Runnable的时候,并没有获得与Thread配套提供的所有功能,所以必须创建一个新的Thread,并将自己传递给它的构建器,以便正式“启动”——start()——一些东西。大家在CBoxVector构建器和go()里都可以体会到这一点。run()方法简单地选择Vector里的一个随机元素编号,并为那个元素调用nextColor(),令其挑选一种新的随机颜色。

  运行这个程序时,大家会发现它确实变得更快,响应也更迅速(比如在中断它的时候,它能更快地停下来)。而且随着网格尺寸的壮大,它也不会经常性地陷于“停顿”状态。因此,线程的处理又多了一项新的考虑因素:必须随时检查自己有没有“太多的线程”(无论对什么程序和运行平台)。若线程太多,必须试着使用上面介绍的技术,对程序中的线程数量进行“平衡”。如果在一个多线程的程序中遇到了性能上的问题,那么现在有许多因素需要检查:

  (1) 对sleep,yield()以及/或者wait()的调用足够多吗?

  (2) sleep()的调用时间足够长吗?

  (3) 运行的线程数是不是太多?

  (4) 试过不同的平台和JVM吗?

  象这样的一些问题是造成多线程应用程序的编制成为一种“技术活”的原因之一。

赞(24)
踩(3)
分享到:
华为认证网络工程师 HCIE直播课视频教程