java线程安全:Java开发中的线程安全选择和Swing

      SwingAPI设计目标是强大、灵活和易用非凡地我们希望能让员们方便地建立新Swing组件不论是从头开始还是通过扩展我们所提供些组件出于这个目我们不要求Swing组件支持多线程访问相反我们向组件发送请求并在单线程中执行请求本文讨论线程和Swing组件不仅是为了帮助你以线程安全方式使用SwingAPI而且解释了我们为什么会选择现在这样线程方案本文包括以下内容:单线程规则:Swing线程在同时刻仅能被个线程所访问般来说这个线程是事件派发线程规则例外:有些操作保证是线程安全事件分发:假如你需要从事件处理或绘制代码以外地方访问UI那么你可以使用SwingUtilities类invokeLater要求在事件派发线程中执行某些代码这个思路方法会立即返回不会等待代码执行完毕invokeAndWait行为和invokeLater类似除了这个思路方法会等待代码执行完毕般地你可以用invokeLater来代替这个思路方法下面是些使用这几个API例子请同时参阅TheJavaTutorial“BINGOexample”尤其是以下几个类:CardWindow、ControlPane、Player和OverallStatusPane使用invokeLater思路方法你可以从任何线程invokeLater思路方法以请求事件派发线程运行特定代码你必须把要运行代码放到个Runnable对象run思路方法中并将此Runnable对象设为invokeLater参数invokeLater思路方法会立即返回不等待事件派发线程执行指定代码这是个使用invokeLater思路方法例子:RunnabledoWorkRunnable=Runnable

};
SwingUtilities.invokeLater;使用invokeAndWait思路方法invokeAndWait思路方法和invokeLater思路方法很相似除了invokeAndWait思路方法会等事件派发线程执行了指定代码才返回在可能情况下你应该尽量用invokeLater来代替invokeAndWait假如你真要使用invokeAndWait请确保invokeAndWait线程不会在期间持有任何其他线程可能需要
这是个使用invokeAndWait例子:voidshowHelloThereDialogthrowsException

};
SwingUtilities.invokeAndWait;
}类似地假设个线程需要对GUI状态进行存取比如文本域内容代码可能类似这样:voidprTextField
throwsException
};
SwingUtilities.invokeAndWait;
.out.prln;}假如你能避免使用线程最好这样做线程可能难于使用并使得debug更困难般来说对于严格意义下GUI工作线程是不必要比如对组件属性更新不管如何说有时候线程是必要下列情况是使用线程些典型情况:执行项费时任务而不必将事件派发线程锁定例子包括执行大量计算情况会导致大量类被装载情况和为网络或磁盘I/O而阻塞情况重复地执行项操作通常在两次操作间间隔个预定时间周期要等待来自客户消息你可以使用两个类来帮助你实现线程:SwingWorker:创建个后台线程来执行费时操作Timer:创建个线程来执行或多次执行某些代码在两次执行间间隔用户定义延迟使用SwingWorker类SwingWorker类在SwingWorker.java中实现这个类并不包含在Java任何发行版中所以你必须单独下载它SwingWorker类做了所有实现个后台线程所需肮脏工作虽然许多都不需要后台线程后台线程在执行费时操作时仍然是很有用它能提高性能观感SwingWorkersanexampleofusingSwingWorker:要使用SwingWorker类你首先要实现它个子类在子类中你必须实现construct思路方法还包含你长时间操作当你例子化SwingWorker子类时SwingWorker创建个线程但并不启动它你要SwingWorker对象start思路方法来启动线程然后start思路方法会construct思路方法当你需要construct思路方法返回对象时可以SwingWorker类get思路方法这是个使用SwingWorker类例子:...//在思路方法中:
finalSwingWorkerworker=SwingWorker
};
worker.start;
...
//在动作事件处理思路方法中:
      JOptionPane.showMessageDialog);当思路方法start思路方法SwingWorker启动个新线程来例子化ExpensiveDialogComponent思路方法还构造了由个窗口和个按钮组成GUI当用户点击按钮将阻塞假如必要阻塞到ExpensiveDialogComponent创建完成然后显示个包含ExpensiveDialogComponent模式对话框你可以在MyApplication.java找到整个使用Timer类Timer类通过个ActionListener来执行或多次执行项操作你创建定时器时候可以指定操作执行频率并且你可以指定定时器动作事件监听者启动定时器后动作监听者actionPerformed思路方法会被来执行操作定时器动作监听者定义actionPerformed思路方法将在事件派发线程中这意味着你不必在其中使用invokeLater思路方法这是个使用Timer类来实现动画循环例子:publicAnimatorApplicationTimer
extendsJFrameimplementsActionListener
publicvoidstartAnimation
}
publicvoidstopAnimation
publicvoidactionPerformed

...
}
      在个线程中执行所有用户界面代码有这样些优点:组件开发者不必对线程编程有深入理解:像ViewPo和Trestle这类工具包中所有组件都必须完全支持多线程访问使得扩展非常困难尤其对不精通线程编程开发者来说最近些工具包如SubArctic和IFC都采用和Swing类似设计事件以可预知次序派发:invokeLater排队runnable对象从鼠标和键盘事件、定时器事件、绘制请求个队列派发些组件完全支持多线程访问工具包中组件改变被变化无常线程调度穿插到事件处理过程中这使得全面测试变得困难甚至不可能更低代价:尝试小心锁住临界区工具包要花费实足时间和空间在锁治理上每当工具包中某个可能在客户代码中实现思路方法时工具包都要保存它状态并释放所有锁以便客户代码能在必要时获得锁当控制权交回到工具包工具包又必须重新抓住它锁并恢复状态所有应用都不得不负担这代价即使大多数应用并不需要对GUI并发访问这是SubArcticJavaToolkit对在工具包中支持多线程访问问题描述:我们基本信条是当设计和建造多线程应用尤其是那些包括GUI组件应用必须保证极端小心线程使用可能会很有欺骗性在许多情况下它们表现得能够极好简化编成使得设计“专注于单任务简单自治实体”成为可能些情况下它们确简化了设计和编码然而在几乎所有情况下它们都使得调试、测试和维护困难大大增加甚至成为不可能无论大多数员所受练习、他们经验和实战还是我们用来帮助自己工具都不是能够用来对付非决定论例如全面测试在bug依靠于时间时是几乎不可能尤其对于Java来说要运行在许多区别类型机器操作系统平台上并且每个都必须在抢先和非抢先式调度下都能正常工作由于这些固有困难我们力劝你 3思是否绝对有使用线程必要尽管如此有些情况下使用线程是必要所以subArctic提供了个线程安全访问机制本章讨论了这机制和怎样在个独立线程中安全地操作交互树他们所说线程安全机制非常类似于SwingUtilities类提供invokeLater和invokeAndWait思路方法

Tags:  什么是线程安全 线程安全 java方法线程安全 java线程安全

延伸阅读

最新评论

发表评论