使用多线程提高GUI响应,以及结束任务的方法

在Java的Swing中,任何一个关于GUI的任务都是用EDT线程(Event Dispatching Thread)完成的,其主要使用的是多个生产者,一个消费者的模式设计的。

 

上述的设计方案的好处是降低消费者EDT线程的复杂性

坏处也显而易见,一旦开发人员编程不当,使用EDT线程去做耗时的任务时,GUI可能就无响应。

 

解决上述问题的办法是,使用Thread-Per-Message Thread Pattern,当一个组件事件发生时,产生一个线程去处理这个任务。

如果涉及到了组件的修改,比如修改Label标签时,可以使用Javax.swing.SwingUtilities.*中的异步执行方法invokeLater(Runnable)或者同步执行方法invokeAndWait(Runnable);

 

比如:

private final JLabel label=new JLabel();

 

invokeLater(new Runnable(){

 public void run(){

   label.setName("Cao Ning is talent");

 }

});

 

解决停止任务的方法是,采用Two-Phase Termination Pattern

 

使用一个标志位,和interrupt()方法。

 

具体的一个例子如下:

public class Main {
    public static void main(String[] args) {
        new MyFrame();
    }
}

 

package Q10_5;

import java.io.IOException;
import java.awt.FlowLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JButton;

public class MyFrame extends JFrame implements ActionListener {
    private final JButton executeButton = new JButton("Execute");
    private final JButton cancelButton = new JButton("Cancel");
    public MyFrame() {
        super("MyFrame");
        getContentPane().setLayout(new FlowLayout());
        getContentPane().add(new JLabel("Two-Phase Termination Sample"));
        getContentPane().add(executeButton);
        getContentPane().add(cancelButton);
        executeButton.addActionListener(this);
        cancelButton.addActionListener(this);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setVisible(true);
    }
    public void actionPerformed(ActionEvent e) {
        if (e.getSource() == executeButton) {
            // 开始执行服务
            Service.service();
        } else if (e.getSource() == cancelButton) {
            // 终止服务
            Service.cancel();
        }
    }
}

package Q10_5;

public class Service {
 private static Thread thread=null;
 private volatile static boolean stop=false;
 
    // 开始执行服务
 public synchronized static void service() {
  if(thread!=null) {
   System.out.print("balking");
   return; //balking
  }
  thread=new Thread() {
   public void run() {
    System.out.print("service");
    try {
     for (int i = 0; i < 50 && stop == false; i++) {
      System.out.print(".");
      Thread.sleep(100);
     }
    } catch (InterruptedException e) {
     System.out.print("interrupted.");
    }
    thread=null;
    stop=false;
    System.out.println("done.");
   }
  };
  thread.start();
 }

    //终止服务
    public static void cancel() {
     if(thread!=null){
      stop=true;
      thread.interrupt();
     }
    }
}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值