java并发之EDT测试

来源:互联网 发布:什么是复杂网络 编辑:程序博客网 时间:2024/05/29 04:45

测试代码如下:

1、耗时计算没有单独起线程处理,耗时计算在EDT线程执行,导致界面没有响应,处于卡死状态

package thread;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.SwingUtilities;public class Test {public static void main(String[] args) {JFrame frame=new JFrame();final JButton button=new JButton();button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubbutton.setLabel("busy");button.setEnabled(false);//ExecutorService executorService=Executors.newCachedThreadPool();//executorService.execute(new Runnable() {////public void run() {// TODO Auto-generated method stubfor (int i = 0; i < 10000000; i++) {System.out.println("operation is running");}//button.setLabel("");//}//});}});button.setSize(50, 20);frame.add(button);frame.setVisible(true);frame.pack();}}


 

 

2、

 

2、起线程处理耗时操作,耗时操作单独在一个线程处理,界面及时响应,没有问题

3、窗体设置部分代码在主线程处理

 4、建议代码如下,对界面的操作应该放在edt线程里去处理,即使是组件的初始化也最好放在EDT中处理,虽然从主线成直接初始化组件发生的错误概率很小,但还是要避免。

上述的SwingUtilites.invokeLater也可有EventQueue.invokeLater代替,这两个方法都是正确的,选择任何一个都可以。实际上,SwingUtilities版只是一个薄薄的封装方法,它直接调用 EventQueue.invokeLater。因为Swing框架本身经常调用SwingUtilities,使用SwingUtilities可以减 少程序引入的类。

第一条规则同通常称为单一线程规则,在任何非EDT线程中都不该接触swing组件。这两条规则看似是矛盾的,既然将耗时的操作放入其他其他线程,那么当耗时操作完成时如何将结果更新到swing组件当中去?因为不能在其他线程中接触swing组件的。其实想想也不难,既然EDT本质上是从事件队列中拿出事件来处理的,那么只要能在其他线程中把耗时操作完成以后再把更细ui组件的代码封装放到事件队列中就行了,到时EDT自然会从事件队列取出代码执行用以达到更新的目的,这样两条规则都满足了。其实在任何线程中,可以使用两种方法想事件队列添加任意的动作。即调用SwingUtilites类(或者EventQueue类也是一样)invokeLater或者invokeAndWait两个静态方法向事件队列添加任务。

 

package thread;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import javax.swing.JButton;import javax.swing.JFrame;import javax.swing.SwingUtilities;public class Test {public static void main(String[] args) {JFrame frame=new JFrame();final JButton button=new JButton();button.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {// TODO Auto-generated method stubbutton.setLabel("busy");button.setEnabled(false);ExecutorService executorService=Executors.newCachedThreadPool();executorService.execute(new Runnable() {public void run() {// TODO Auto-generated method stubfor (int i = 0; i < 10000000; i++) {System.out.println("operation is running");}//对gui组建的操作放在edt线程处理SwingUtilities.invokeLater(new Runnable() {public void run() {// TODO Auto-generated method stubbutton.setLabel("");}});}});}});//界面的初始化其实也不应该放在主线程执行,应该放在edt线程,虽然出错的概率不大button.setSize(50, 20);frame.add(button);frame.setVisible(true);frame.pack();}}


原创粉丝点击