java edt,java并发之EDT测试

测试代码如下:

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 stub

button.setLabel("busy");

button.setEnabled(false);

//ExecutorService executorService=Executors.newCachedThreadPool();

//executorService.execute(new Runnable() {

//

//public void run() {

// TODO Auto-generated method stub

for (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、

0818b9ca8b590ca3270a3433284dd417.png

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

0818b9ca8b590ca3270a3433284dd417.png

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

0818b9ca8b590ca3270a3433284dd417.png

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 stub

button.setLabel("busy");

button.setEnabled(false);

ExecutorService executorService=Executors.newCachedThreadPool();

executorService.execute(new Runnable() {

public void run() {

// TODO Auto-generated method stub

for (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 stub

button.setLabel("");

}

});

}

});

}

});

//界面的初始化其实也不应该放在主线程执行,应该放在edt线程,虽然出错的概率不大

button.setSize(50, 20);

frame.add(button);

frame.setVisible(true);

frame.pack();

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值