JAVA中的异步
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();
}
});
}
}
使用以下几个步骤:
1.使用SwingWorker子类,将高耗时好资源的操作放置到doBackGround()方法中实现,并在操作中通过setProgress()方法设置这种耗时操作的进度情况。
当然这个操作是在子线程中完成 ,SwingWorker已经帮我们实现,我们不必拘泥实现过程。
2.在form的页面中含有2个重要的因素 两个触发点
1)高耗时操作 消耗资源操作的开始触发点 本例演示的是Button的点击触发
2)由于耗时操作导致进度属性改变触发了 进度条的进度的改变 这个触发点是任务的进度改变 这里是通过了一个事件PropertyChangeEvent实现
本例步骤如下:
1)添加mytask类,在dobackgroud方法中加入业务代码 setprogress设置进度
2)form雷的button中注册ActionListener事件 事件的回调中加入耗时任务开始的代码 task.execute();
3)form类中的progressbar注册PropertyChangeEvent事件 事件回调中加入 设置季度条进度的代码 bar3.setValue(1111);
4)如果要获取任务执行完成后最终需要使用的数据可以通过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 javax.xml.ws.AsyncHandler;
import javax.xml.ws.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;
}
}