Java开发中的线程安全选择与Swing

2016-02-19 12:32 15 1 收藏

每个人都希望每天都是开心的,不要因为一些琐事扰乱了心情还,闲暇的时间怎么打发,关注图老师可以让你学习更多的好东西,下面为大家推荐Java开发中的线程安全选择与Swing,赶紧看过来吧!

【 tulaoshi.com - 编程语言 】

  Swing API的设计目标是强大、灵活和易用。非凡地,我们希望能让程序员们方便地建立新的Swing组件,不论是从头开始还是通过扩展我们所提供的一些组件。
  
  出于这个目的,我们不要求Swing组件支持多线程访问。相反,我们向组件发送请求并在单一线程中执行请求。
  
  本文讨论线程和Swing组件。目的不仅是为了帮助你以线程安全的方式使用Swing API,而且解释了我们为什么会选择现在这样的线程方案。
  
  本文包括以下内容:
   单线程规则:Swing线程在同一时刻仅能被一个线程所访问。一般来说,这个线程是事件派发线程(event-dispatching thread)。
  
   规则的例外:有些操作保证是线程安全的。
  
   事件分发:假如你需要从事件处理(event-handling)或绘制代码以外的地方访问UI,那么你可以使用SwingUtilities类的invokeLater()或invokeAndWait()方法。
  
   创建线程:假如你需要创建一个线程比如用来处理一些耗费大量计算能力或受I/O能力限制的工作你可以使用一个线程工具类如SwingWorker或Timer。
  
   为什么我们这样实现Swing:我们将用一些关于Swing的线程安全的背景资料来结束这篇文章。
  
  Swing的规则是:
  
  一旦Swing组件被具现化(realized),所有可能影响或依靠于组件状态的代码都应该在事件派发线程中执行。
  
  这个规则可能听起来有点吓人,但对许多简单的程序来说,你用不着为线程问题操心。在我们深入如何撰写Swing代码之前,让我们先来定义两个术语:具现化(realized)和事件派发线程(event-dispatching thread)。
  
  具现化的意思是组建的paint()方法已经或可能会被调用。一个作为顶级窗口的Swing组件当调用以下方法时将被具现化:setVisible(true)、show()或(可能令你惊异)pack()。当一个窗口被具现化,它包含的所有组件都被具现化。另一个具现化一个组件的方法是将它放入到一个已经具现化的容器中。稍后你会看到一些对组件具现化的例子。
  
  事件派发线程是执行绘制和事件处理的线程。例如,paint()和actionPerformed()方法会自动在事件派发线程中执行。另一个将代码放到事件派发线程中执行的方法是使用SwingUtilities类的invokeLater()方法。
  
  所有可能影响一个已具现化的Swing组件的代码都必须在事件派发线程中执行。但这个规则有一些例外:
  
  有些方法是线程安全的:在Swing API的文档中,线程安全的方法用以下文字标记:
  
  This method is thread safe, although most Swing methods are not.
  (这个方法是线程安全的,尽管大多数Swing方法都不是。)
  
  一个应用程序的GUI经常可以在主线程中构建和显示:下面的典型代码是安全的,只要没有(Swing或其他)组件被具现化:
  
  public class MyApplication
  {
   public static void main(String[] args)
   {
  JFrame f = new JFrame("Labels"); // 在这里将各组件
   // 加入到主框架
   f.pack();
   f.show();
   // 不要再做任何GUI工作
    }
  }
  
  上面所示的代码全部在main线程中运行。对f.pack()的调用使得JFrame以下的组件都被具现化。这意味着,f.show()调用是不安全的且应该在事件派发线程中执行。尽管如此,只要程序还没有一个看得到的GUI,JFrame或它的里面的组件就几乎不可能在f.show()返回前收到一个paint()调用。因为在f.show()调用之后不再有任何GUI代码,于是所有GUI工作都从主线程转到了事件派发线程,因此前面所讨论的代码实际上是线程安全的。
  
  一个applet的GUI可以在init()方法中构造和显示:现有的浏览器都不会在一个applet的init()和start()方法被调用前绘制它。因而,在一个applet的init()方法中构造GUI是安全的,只要你不对applet中的对象调用show()或setVisible(true)方法。
  
  要顺便一提的是,假如applet中使用了Swing组件,就必须实现为JApplet的子类。并且,组件应该添加到的JApplet内容窗格(content pane)中,而不要直接添加到JApplet。对任何applet,你都不应该在init()或start()方法中执行费时的初始化操作;而应该启动一个线程来执行费时的任务。
  
  下述JComponent方法是安全的,可以从任何线程调用:repaint()、revalidate()、和invalidate()。

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

来源:http://www.tulaoshi.com/n/20160219/1601122.html

延伸阅读
众所周知,java为开发语言提供了很方便的开发平台,但开发出来的程序很容易在不同的平台上面被移植,现在越来越多的人使用它开发软件。 Java有它方便的一个方面,但它同时也带给了开发者一个烦恼,这就是保护的办法不多,而且大多数不是很好用,这样自己辛苦开发出来的程序很容易被人复制而据为己有,一般情况下,大多数的人都是用混编器(j...
在Java的多线程编程中,java.lang.Thread类型包含了一些列的方法start(), stop(), stop(Throwable) and suspend(), destroy() and resume()。通过这些方法,我们可以对线程进行方便的操作,但是这些方法中,只有start()方法得到了保留。 在Sun公司的一篇文章《Why are Thread.stop, Thread.suspend and Thread.resume Deprecated? 》中详细讲...
标签: Web开发
代码如下: style BODY {FONT-SIZE: 9pt;} table {FONT-SIZE: 9pt;} /style input type=checkbox id=checkall onclick=check_all()label for=checkall全部选择/label 线程数:input type=text id=the_thread value=10 size=2 maxlength=2 style="height:...
一 抛砖引玉 本文指在利用一个小程序”Swing 组件大全”来引导大家学习Java这门语言,熟悉Java Swing的各个组件。并在学习过程中参考作者设计这一程序的方法和思想,最终形成自己的思维方式和学习方式。你能举一返三是作者最开心的事情。 !-- frame contents -- !-- /frame contents -- 小程序演示了Java Swing大部分组...
摘 要:使用Java对WEB静态图像进行分割重组,然后根据用户的交互操作合成显示,并利用线程对程序的并发性加以控制,从而达到图像显示的动态性和交互性效果。 要害词:Java语言 类Class 线程Thread Java是一种面向对象的编程语言。它具有与平台无关、面向对象、动态、安全等特点,答应直接使用多线程方式进行编程,...

经验教程

800

收藏

47
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部