知识大全 针对用户界面的多线程

Posted

篇首语:历史是一面镜子,它照亮现实,也照亮未来。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 针对用户界面的多线程相关的知识,希望对你有一定的参考价值。

  现在 我们也许能用一个线程解决在Counter java中出现的问题 采用的一个技巧便是在一个线程的run()方法中放置 子任务 ——亦即位于go()内的循环 一旦用户按下Start按钮 线程就会启动 但马上结束线程的创建 这样一来 尽管线程仍在运行 但程序的主要工作却能得以继续(等候并响应用户界面的事件) 下面是具体的代码   //: Counter java  // A responsive user interface with threads  import java awt *;  import java awt event *;  import java applet *;  class SeparateSubTask extends Thread    private int count = ;   private Counter c ;   private boolean runFlag = true;   public SeparateSubTask(Counter c )    this c = c ;   start();      public void invertFlag() runFlag = !runFlag;   public void run()    while (true)    try    sleep( );   catch (InterruptedException e)   if(runFlag)    c t setText(Integer toString(count++));           public class Counter extends Applet    TextField t = new TextField( );   private SeparateSubTask sp = null;   private Button    onOff = new Button( Toggle )    start = new Button( Start );   public void init()    add(t);   start addActionListener(new StartL());   add(start);   onOff addActionListener(new OnOffL());   add(onOff);      class StartL implements ActionListener    public void actionPerformed(ActionEvent e)    if(sp == null)   sp = new SeparateSubTask(Counter this);         class OnOffL implements ActionListener    public void actionPerformed(ActionEvent e)    if(sp != null)   sp invertFlag();         public static void main(String[] args)    Counter applet = new Counter ();   Frame aFrame = new Frame( Counter );   aFrame addWindowListener(   new WindowAdapter()    public void windowClosing(WindowEvent e)    System exit( );      );   aFrame add(applet BorderLayout CENTER);   aFrame setSize( );   applet init();   applet start();   aFrame setVisible(true);       现在 Counter 变成了一个相当直接的程序 它的唯一任务就是设置并管理用户界面 但假若用户现在按下Start按钮 却不会真正调用一个方法 此时不是创建类的一个线程 而是创建SeparateSubTask 然后继续Counter 事件循环 注意此时会保存SeparateSubTask的句柄 以便我们按下onOff按钮的时候 能正常地切换位于SeparateSubTask内部的runFlag(运行标志) 随后那个线程便可启动(当它看到标志的时候) 然后将自己中止(亦可将SeparateSubTask设为一个内部类来达到这一目的)   SeparateSubTask类是对Thread的一个简单扩展 它带有一个构建器(其中保存了Counter 句柄 然后通过调用start()来运行线程)以及一个run()——本质上包含了Counter java的go()内的代码 由于SeparateSubTask知道自己容纳了指向一个Counter 的句柄 所以能够在需要的时候介入 并访问Counter 的TestField(文本字段)   按下onOff按钮 几乎立即能得到正确的响应 当然 这个响应其实并不是 立即 发生的 它毕竟和那种由 中断 驱动的系统不同 只有线程拥有CPU的执行时间 并注意到标记已发生改变 计数器才会停止    用内部类改善代码  下面说说题外话 请大家注意一下SeparateSubTask和Counter 类之间发生的结合行为 SeparateSubTask同Counter 亲密 地结合到了一起——它必须持有指向自己 父 Counter 对象的一个句柄 以便自己能回调和操纵它 但两个类并不是真的合并为单独一个类(尽管在下一节中 我们会讲到Java确实提供了合并它们的方法) 因为它们各自做的是不同的事情 而且是在不同的时间创建的 但不管怎样 它们依然紧密地结合到一起(更准确地说 应该叫 联合 ) 所以使程序代码多少显得有些笨拙 在这种情况下 一个内部类可以显著改善代码的 可读性 和执行效率   //: Counter i java  // Counter using an inner class for the thread  import java awt *;  import java awt event *;  import java applet *;  public class Counter i extends Applet    private class SeparateSubTask extends Thread    int count = ;   boolean runFlag = true;   SeparateSubTask() start();    public void run()    while (true)    try    sleep( );   catch (InterruptedException e)   if(runFlag)    t setText(Integer toString(count++));            private SeparateSubTask sp = null;   private TextField t = new TextField( );   private Button    onOff = new Button( Toggle )    start = new Button( Start );   public void init()    add(t);   start addActionListener(new StartL());   add(start);   onOff addActionListener(new OnOffL());   add(onOff);      class StartL implements ActionListener    public void actionPerformed(ActionEvent e)    if(sp == null)   sp = new SeparateSubTask();         class OnOffL implements ActionListener    public void actionPerformed(ActionEvent e)    if(sp != null)   sp runFlag = !sp runFlag; // invertFlag();         public static void main(String[] args)    Counter i applet = new Counter i();   Frame aFrame = new Frame( Counter i );   aFrame addWindowListener(   new WindowAdapter()    public void windowClosing(WindowEvent e)    System exit( );      );   aFrame add(applet BorderLayout CENTER);   aFrame setSize( );   applet init();   applet start();   aFrame setVisible(true);       这个SeparateSubTask名字不会与前例中的SeparateSubTask冲突——即使它们都在相同的目录里——因为它已作为一个内部类隐藏起来 大家亦可看到内部类被设为private(私有)属性 这意味着它的字段和方法都可获得默认的访问权限(run()除外 它必须设为public 因为它在基础类中是公开的) 除Counter i之外 其他任何方面都不可访问private内部类 而且由于两个类紧密结合在一起 所以很容易放宽它们之间的访问限制 在SeparateSubTask中 我们可看到invertFlag()方法已被删去 因为Counter i现在可以直接访问runFlag   此外 注意SeparateSubTask的构建器已得到了简化——它现在唯一的用外就是启动线程 Counter i对象的句柄仍象以前那样得以捕获 但不再是通过人工传递和引用外部对象来达到这一目的 此时的内部类机制可以自动照料它 在run()中 可看到对t的访问是直接进行的 似乎它是SeparateSubTask的一个字段 父类中的t字段现在可以变成private 因为SeparateSubTask能在未获任何特殊许可的前提下自由地访问它——而且无论如何都该尽可能地把字段变成 私有 属性 以防来自类外的某种力量不慎地改变它们   无论在什么时候 只要注意到类相互之间结合得比较紧密 就可考虑利用内部类来改善代码的编写与维护 cha138/Article/program/Java/gj/201311/27450

相关参考

知识大全 Linux下的多线程编程

Linux下的多线程编程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  引言    线程(thr

知识大全 详细讲解C#的多线程能力

详细讲解C#的多线程能力  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  线程是允许进行并行计算的

知识大全 基于.NET的多线程编程入门

基于.NET的多线程编程入门  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!多线程在构建大型系统的时

知识大全 解析Java的多线程机制

解析Java的多线程机制  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一进程与应用程序的区别 

知识大全 Java程序中的多线程

Java程序中的多线程  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一为什么会排队等待?  下

知识大全 Java 程序中的多线程(四)

Java程序中的多线程(四)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  作者NeelVKum

知识大全 Java 程序中的多线程(二)

Java程序中的多线程(二)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  作者NeelVKum

知识大全 Java 程序中的多线程(一)

Java程序中的多线程(一)  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  作者NeelVKum

知识大全 Heritrix的多线程ToeThread和ToePool

Heritrix的多线程ToeThread和ToePool  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一

知识大全 .NET下的多线程编程应用程序域

.NET下的多线程编程应用程序域  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  一应用程序域&n