Java线程_04
来源:互联网 发布:cad软件安装教程 编辑:程序博客网 时间:2024/05/21 18:35
线程与Java Swing
Java Swing非线程安全
多线程情况下访问Swing对象必须要遵守特殊的规则(保证只从单一线程来访问Swing对象)。
Swing程序会有多个线程,其中事件派发线程负责对所有Swing对象的访问和对象状态修改,保持所有对Swing对象的访问都被事件派发线程发出是排查多线程问题非常重要的关注点。
例外和规则
- 未呈现的Swing对象可被任何的thread创建与操作,但当Swing对象已经被呈现,则就只能通过事件派发线程来访问。
- Swing组件的repaint方法可以从任何的thread调用
- invokeLater()方法可以从任何thread调用
- invokeAndWait方法可以从任何不是事件派发的thread调用
示例_模拟处理耗时任务
package org.ybygjy.thread3th.demo2;import java.awt.GridLayout;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.HashMap;import java.util.Map;import java.util.Observable;import java.util.Observer;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JTextField;import javax.swing.SwingUtilities;import javax.swing.border.TitledBorder;/** * 线程与Swing * @author WangYanCheng * @version 2012-10-31 */public class SwingThread extends JFrame implements Observer { /** * serial ID */ private static final long serialVersionUID = 6365731511993325046L; /** 全局对象 */ private Map<String, JTextField> context; /** 输入类组件ID前缀 */ private static String INPUT_FIELD_PREFIX = "INS_"; /** 输出类组件ID前缀 */ private static String OUTPUT_FIELD_PREFIX = "OUS_"; /** * Constructor */ public SwingThread() { context = new HashMap<String, JTextField>(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel ctxPanel = new JPanel(); ctxPanel.setBorder(new TitledBorder("计算斐波那契数:")); System.out.println(getContentPane().getLayout()); GridLayout glInst = new GridLayout(10, 1); ctxPanel.setLayout(glInst); getContentPane().add(ctxPanel); createTask(ctxPanel); pack(); } /** * 创建任务 * @param mainPanel 主面板 */ private void createTask(JPanel mainPanel) { for (int i = 1; i <= 10; i++) { JLabel tmplJLIn = new JLabel("输入:"); JLabel tmplJLOu = new JLabel("输出:"); JPanel jp = new JPanel(); jp.setBorder(new TitledBorder("第".concat(String.valueOf(i)).concat("组"))); jp.add(tmplJLIn); JTextField jtf = new JTextField(5); final String inputKey = INPUT_FIELD_PREFIX.concat(String.valueOf(i)); regInsComp(inputKey, jtf); jp.add(jtf); jp.add(tmplJLOu); JTextField jtfo = new JTextField(5); final String outputKey = OUTPUT_FIELD_PREFIX.concat(String.valueOf(i)); regInsComp(outputKey, jtfo); jp.add(jtfo); JButton jtnBtn = new JButton("计算"); jtnBtn.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { FibBean fbInst = new FibBean(); fbInst.setInputKey(inputKey); fbInst.setOutputKey(outputKey); fbInst.setFibTerm(getInsValue(inputKey)); new FibonacciTask(SwingThread.this, fbInst); } }); jp.add(jtnBtn); mainPanel.add(jp); } } /** * 注册组件 * @param key key * @param jtf obj */ private void regInsComp(String key, JTextField jtf) { context.put(key, jtf); } /** * 取组件值 * @param key key * @return rtnV 默认为0 */ private long getInsValue(String key) { return context.containsKey(key) ? Integer.parseInt(context.get(key).getText()) : 0; } /** * 测试入口 * @param args 参数列表 */ public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { new SwingThread().setVisible(true); } }); } /** * {@inheritDoc} */ public void update(Observable o, Object arg) { if (arg instanceof FibBean) { final FibBean fibBean = (FibBean) arg; SwingUtilities.invokeLater(new Runnable() { public void run() { context.get(fibBean.getOutputKey()).setText(String.valueOf(fibBean.getFibValue())); } }); } }}
package org.ybygjy.thread3th.demo2;import java.util.Observable;import java.util.Observer;/** * FibonacciTask * @author WangYanCheng * @version 2012-11-1 */public class FibonacciTask extends Observable implements Runnable { /**{@link FibBean}*/ private FibBean fibBean; /** * Constructor * @param observer {@link Observer} * @param fibBean fibBean */ public FibonacciTask(Observer observer, FibBean fibBean) { this.fibBean = fibBean; addObserver(observer); new Thread(this).start(); } /** * {@inheritDoc} */ public void run() { this.fibBean.setFibValue(calc(this.fibBean.getFibTerm())); setChanged(); notifyObservers(this.fibBean); } /** * 计算逻辑(递归) * @param fibNum 项数 * @return rtnV */ private long calc(long fibNum) { if (fibNum <= 2) { return 1; } return (calc(fibNum - 1) + calc(fibNum - 2)); }}
package org.ybygjy.thread3th.demo2;/** * 数据Bean * @author WangYanCheng * @version 2012-11-1 */public class FibBean { /**输入对象Key*/ private String inputKey; /**输出对象Key*/ private String outputKey; /**Fibonacci项*/ private long fibTerm; /**Fibonacci值*/ private long fibValue; /** * @return the inputKey */ public String getInputKey() { return inputKey; } /** * @param inputKey the inputKey to set */ public void setInputKey(String inputKey) { this.inputKey = inputKey; } /** * @return the outputKey */ public String getOutputKey() { return outputKey; } /** * @param outputKey the outputKey to set */ public void setOutputKey(String outputKey) { this.outputKey = outputKey; } /** * @return the fibTerm */ public long getFibTerm() { return fibTerm; } /** * @param fibTerm the fibTerm to set */ public void setFibTerm(long fibTerm) { this.fibTerm = fibTerm; } /** * @return the fibValue */ public long getFibValue() { return fibValue; } /** * @param fibValue the fibValue to set */ public void setFibValue(long fibValue) { this.fibValue = fibValue; }}
- Java线程_04
- java基础总结_04
- Java学习笔记_04
- Java工具集介绍11_04
- 第一章_04开发Java程序上
- java学习_04.1_参数传递
- JAVA语言学习_04(类的toString()方法)
- java虚拟机_04程序编译与代码优化
- Java从基础开始_04集合的体系
- Java千百问_04异常处理(001)_什么是java中的异常
- 《Java就业培训教程》_张孝祥_书内源码_04
- JAVA高级01_04 基本数据类型的对象包装类 2011-4-20
- 黑马程序员--JAVA基础_04(接口、多态、内部类、异常)
- Java千百问_04异常处理(002)_java如何捕获异常
- Java千百问_04异常处理(003)_如何抛出异常
- Java千百问_04异常处理(004)_finally关键字如何使用
- Java千百问_04异常处理(005)_如何自定义异常
- Java千百问_04异常处理(008)_java中常见的错误有哪些
- 如何解决AIX的文件系统故障
- [cocos2d-x 学习] 第一个cocos2d-x win32程序和NDK交叉编译
- Windows Phone 7 开发 31 日谈——第8日:选择器
- Linux C 经典题目总结
- 要想坐着无所事事,你必须坐在非常、非常高的位置
- Java线程_04
- hdu 4300 Clairewd’s message
- 面向对象(三)之多态
- uva 10564 Paths through the Hourglass
- mysql卸载后重装失败的解决方法
- DIV和SPAN的区别
- Ext昨日问题,是否是bug?
- panel的visible属性影响页面布局
- graphics shaders: discard vs transparency