FORM程序的异步

本示例演示JAVA Form项目的异步处理的一个结构,JAVA是采用一个事件模型来处理异步的情况

1.耗时操作的task


package form.demo.async;
 
import javax.swing.SwingWorker;
 
/**自定义耗时任务累
 * SwingWorker<String, Integer>表示执行最终完成 将可以通过mytask.get()方法获取一个返回值为string的数据 Integer表示事件在运行中返回的实时数据(并不是进度) 设置进度一定是setProgress(int)方法
 * @author Administrator
 *
 */
public class mytask extends SwingWorker<String, Integer> {
 
    /*
     * 后台操作
     */
    @Override
    protected String doInBackground() throws Exception {
       // TODO Auto-generated method stub
 
       for (int i = 1; i < 11; i++) {
           Thread.sleep(i * 1000);
           this.setProgress(i * 10);
       } 
       //耗时操作最终的返回值为Hello
       return "Hello";
    }
 
}

2.form页的程序

package form.demo.async;
 
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
 
import javax.swing.*;
 
/**自定义窗体
 * @author Administrator
 *
 */
public class Jform extends JFrame {
    JProgressBar bar3 = new JProgressBar();
    mytask task = new mytask();
 
    private static final long serialVersionUID = 1L;
 
    /**
     * 窗体相关绘制
     */
    public Jform() {
       this.setSize(500, 300);
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       FlowLayout flowLayout = new FlowLayout();
       setLayout(flowLayout);
       this.initTask3Control();
       this.setVisible(true);
       //为task对象注册属性改变事件
       task.addPropertyChangeListener(new PropertyChangeListener() {
           @Override
           public void propertyChange(PropertyChangeEvent evt) {
              // TODO Auto-generated method stub
              bar3.setValue((Integer) evt.getNewValue());
           }
       });
    }
 
    
    
    private void initTask3Control() {
       JButton btn3 = new JButton("开启"); 
       bar3.setStringPainted(true);
       bar3.setForeground(Color.BLUE); 
       bar3.setMinimum(0); 
       bar3.setMaximum(100);
       this.add(bar3);
       this.add(btn3);
       //为button对象注册点击事件
       btn3.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent e) {
              // TODO Auto-generated method stub
              task.execute();
           }
       });
 
    }
 
}

 

 

 

 

使用以下几个步骤:

使用SwingWorker子类,将高耗时好资源的操作放置到doBackGround()方法中实现,并在操作中通过setProgress()方法设置这种耗时操作的进度情况。

当然这个操作是在子线程中完成 ,SwingWorker已经帮我们实现,我们不必拘泥实现过程。

在form的页面中含有2个重要的因素 两个触发点

)高耗时操作 消耗资源操作的开始触发点 本例演示的是Button的点击触发

)由于耗时操作导致进度属性改变触发了 进度条的进度的改变 这个触发点是任务的进度改变 这里是通过了一个事件PropertyChangeEvent实现

   

   

本例步骤如下:

)添加mytask类,在dobackgroud方法中加入业务代码 setprogress设置进度

雷的button中注册ActionListener事件 事件的回调中加入耗时任务开始的代码

)form类中的progressbar注册PropertyChangeEvent事件 事件回调中加入 设置季度条进度的代码

如果要获取任务执行完成后最终需要使用的数据可以通过task.get()方法获取

其他后台的异步操作 避免线程阻塞

1.通过线程池管理异步任务

package asyncTask;
 
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
 
/**此实例 演示使用线程池管理异步任务
 * @author Administrator 
 */
public class TestMain {
 
    
    public static void main(String[] args) throws InterruptedException,
           ExecutionException {
       //new TestMain().exec(); 
    }
      
    // 类似与run方法的实现 Callable是一个接口,在call中手写逻辑代码
    Callable<Integer> callable = new Callable<Integer>() {
        
       @Override
       public Integer call() throws Exception {
           Integer res = new Random().nextInt(100);
           Thread.sleep(1000);
           System.out.println("任务执行:获取到结果 :" + res);
           return res;
       }
    }; 
    
    void exec() throws InterruptedException, ExecutionException {
       // 进行异步任务列表
       List<FutureTask<Integer>> futureTasks = new ArrayList<FutureTask<Integer>>();  
       // 线程池 初始化十个线程 和JDBC连接池是一个意思 实现重用 此线程池能装10个线程
       ExecutorService executorService = Executors.newFixedThreadPool(10); 
       long start = System.currentTimeMillis(); 
       for (int i = 0; i < 10; i++) {
           // 创建一个异步任务
           FutureTask<Integer> futureTask = new FutureTask<Integer>(callable); 
           futureTasks.add(futureTask);
           // 提交异步任务到线程池,让线程池管理任务 特爽把。 由于是异步并行任务,所以这里并不会阻塞
           executorService.submit(futureTask);
       }
 
       int count = 0;
       for (FutureTask<Integer> futureTask : futureTasks) {
           // futureTask.get() 得到我们想要的结果
           // 该方法有一个重载get(long timeout, TimeUnit unit) 第一个参数为最大等待时间,第二个为时间的单位
           count += futureTask.get();
       }
       long end = System.currentTimeMillis();
       System.out.println("线程池的任务全部完成:结果为:" + count + ",main线程关闭,进行线程的清理");
       System.out.println("使用时间:" + (end - start) + "ms");
       // 清理线程池
       executorService.shutdown();
 
    }
}

得到异步任务的执行结果

package asyncTask; 
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
 
/**此示例演示获得异步任务的处理结果 task.get()方法  task.run()开始运行异步任务
 * @author Administrator
 *
 */
public class testMain1 {
 
    public static void main(String[] args) throws InterruptedException,ExecutionException {
       new testMain1().showResult();
    }
 
    public void showResult() throws InterruptedException, ExecutionException {
       Callable<Integer> Bigwork = new Callable<Integer>() {
 
           @Override
           public Integer call() throws Exception {
              Integer res = new Random().nextInt(1009);
 
              for (int i = 1; i <= 10; i++) {
                  System.out.println("在艰难的运行中!"+i+"秒");
                  Thread.sleep(1000);
              } 
              return res;
           }
       };
 
       FutureTask<Integer> task = new FutureTask<Integer>(Bigwork);
       //运行异步任务
       task.run();
       //得到异步任务运行的结果
       System.out.println(task.get());
    }
 
}

 

异步任务 返回任务进度

package asyncTask; 
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException; 
import .AsyncHandler;
import .Response;
 
/**
 * 此示例演示 异步任务重返回任务进度
 * 
 * @author Administrator 
 */
public class testMain2 {
 
    public static AsyncHandler<Integer> asDemo = new AsyncHandler<Integer>() {
 
       @Override
       public void handleResponse(Response<Integer> res) {
           try {
              System.out.println("处理了+" + res.get() * 10 + "%");
           } catch (InterruptedException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
           } catch (ExecutionException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
           }
       }
 
    };
 
    public static void main(String[] args) throws InterruptedException,
           ExecutionException {
 
       Callable<Integer> Bigwork = new Callable<Integer>() {
 
           @Override
           public Integer call() throws Exception {
              Integer res = new Random().nextInt(1009);
 
              for (Integer i = 1; i <= 10; i++) {
                  Thread.sleep(1000);
                  testMain2.asDemo.handleResponse(new Rep(i));
              }
 
              return res;
           }
       };
 
       FutureTask<Integer> task = new FutureTask<Integer>(Bigwork);
       // 运行异步任务
       task.run();
       // 得到异步任务运行的结果
       System.out.println("异步任务最终结果为:" + task.get());
 
    }
 
}
 
/**
 * 继承响应结果 传入进度
 * 
 * @author Administrator
 *
 */
class Rep implements Response<Integer> {
 
    int timeout;
 
    public Rep(int timeout) {
       this.timeout = timeout;
    }
 
    @Override
    public boolean cancel(boolean mayInterruptIfRunning) {
       // TODO Auto-generated method stub
       return false;
    }
 
    @Override
    public boolean isCancelled() {
       // TODO Auto-generated method stub
       return false;
    }
 
    @Override
    public boolean isDone() {
       // TODO Auto-generated method stub
       return false;
    }
 
    @Override
    public Integer get() throws InterruptedException, ExecutionException {
       // TODO Auto-generated method stub
       return this.timeout;
    }
 
    @Override
    public Integer get(long timeout, TimeUnit unit)
           throws InterruptedException, ExecutionException, TimeoutException {
       // TODO Auto-generated method stub
       return null;
    }
 
    @Override
    public Map<String, Object> getContext() {
       // TODO Auto-generated method stub
       return null;
    }
}