代码下载:http://download.csdn.net/detail/b275518834/7937005
我们在开发前台的时候经常遇到各种各样异步的处理。
比如耗时的操作放到线程里,如果需要询问用户,然后再继续线程。该怎么做呢?
如安装向导,服务器等待应答,错误回滚,重定向新的游戏服务器
代码当然不难,可是异步的代码非常的难看,synchronized和唤醒跳转关系,让代码阅读困难。
尤其在android有AsynTask 和Handler,不怕实现就怕维护。
我这里介绍我工作中遇到的问题,我写了个的demo来重构自己的代码。
例子:我们生活中经常遇到很多异步处理,小明在工作,突然接到电话,小明放下手中的工作,接完电话小明继续工作
分析:执行线程,弹出对话框,等待用户输入,继续执行线程中剩余动作。
如图
第一遍编写-失败案例,整个代码中充满await()和astart();方法业务逻辑无法体现
package com.test; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; import javax.swing.JOptionPane; //常规写法 public class Test { public static ReentrantLock lock = new ReentrantLock(); public static Condition condition = lock.newCondition(); public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub new Thread() { @Override public void run() { System.out.println("小明在工作"); timerWait(5000); System.out.println("小明接到电话,放下工作"); astart(); await(); System.out.println("小明继续工作"); timerWait(2000); astart(); } }.start(); System.out.println("主线程堵塞"); await(); JOptionPane.showMessageDialog(null, "接到电话,放下工作", "消息提示", JOptionPane.ERROR_MESSAGE); astart(); System.out.println("小明工作结束结束"); } private static void await() { lock.lock(); try { condition.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } lock.unlock(); } private static void astart() { lock.lock(); condition.signal(); lock.unlock(); } private static void timerWait(int i) { // TODO Auto-generated method stub try { Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
主函数 这是重构以后,将业务逻辑和跳转关系明确出来
package com.demo; import javax.swing.JOptionPane; //流程写法 public class MainTest_AsynCallTask { public static void main(String[] args) { new AsynCallTask() { @SuppressWarnings("unused") public void call1() throws InterruptedException { System.out.println("小明做工作"); Thread.sleep(2000); } @SuppressWarnings("unused") public void call2() throws InterruptedException { System.out.println("接到电话,先放下工作,等待电话结束"); JOptionPane.showMessageDialog(null, "接到电话,放下手中工作!", "接到电话", JOptionPane.ERROR_MESSAGE); Thread.sleep(2000); } @Override protected synchronized boolean excute(int state) { switch (state) { case 0: postStateByMethod("call1", 1); break; case 1: postStateByMethod("call2", 2); break; case 2: System.out.println("电话结束"); postCallBack(new CallBackAction() { //如何在一个新线程中唤醒 <span style="font-family: Arial, Helvetica, sans-serif;">excute(int state)</span> @Override public void call(final AsynCallTask task) { // TODO Auto-generated method stub new Thread() { @Override public void run() { System.out.println("小明继续工作"); try { Thread.sleep(2000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } postExcute(3); } }.start(); } }); break; default: System.out.println("小明工作结束"); return false; } return true; } }; } }
封装类
package com.demo; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; public abstract class AsynCallTask implements Runnable { /**状态码*/ protected int state; /**重入锁*/ private ReentrantLock lock = new ReentrantLock(); /**线程锁条件*/ private Condition condition = lock.newCondition(); /**获得自身引用,在postStateByMethod方法中方便获取获取class*/ private AsynCallTask task; /**最大值为2的线程队列*/ private ExecutorService service = Executors.newFixedThreadPool(2); { task=this;//获得自身引用 service.submit(this);//执行自身线程 } /**最大值为2的线程队列*/ @Override public void run() { // TODO Auto-generated method stub while(excute(state));//重复进入excute(state)方法直到return false service.shutdown();//执行结束时关闭队列 service=null; task=null; } protected abstract boolean excute(int state); /**当前线程等待*/ protected final void stop() { lock.lock(); try { condition.await(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } lock.unlock(); } /**唤醒其他线程*/ protected final void start() { lock.lock(); condition.signalAll(); lock.unlock(); } /**设置状态码并且唤醒其他线程*/ protected final void postExcute(Integer state) { this.state = state; start(); } /**等待AsynCallTask run方法,执行一段新的Run方法*/ protected void postCallBack(CallBackAction run) { lock.lock(); service.submit(run); stop(); lock.unlock(); } /**等待AsynCallTask run方法,指定方法执行*/ public void postByMethod(final String str) { postCallBack(new CallBackAction() { @Override public void call(AsynCallTask task) { try { task.getClass().getMethod(str).invoke(task); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }); } /**等待AsynCallTask run方法,指定方法执行,结束后指定状态码唤醒AsynCallTask的run方法*/ public void postStateByMethod(final String str,final int state) { this.state=state; postCallBack(new CallBackAction() { @Override public void call(AsynCallTask task) { try { task.getClass().getMethod(str).invoke(task); } catch (Exception e) { } postExcute(state); } }); } /**等待回调接口*/ private interface CallBack extends Runnable { public void call(AsynCallTask task); } public abstract class CallBackAction implements CallBack { @Override public final void run() { call(AsynCallTask.this); } @Override public abstract void call(AsynCallTask task); } }
package com.test.asyn; import android.app.Activity; import android.app.AlertDialog; import android.app.AlertDialog.Builder; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.os.Bundle; import android.widget.ProgressBar; import android.widget.SeekBar; public class StartActivity extends Activity{ SeekBar bar; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.main); bar=(SeekBar) findViewById(R.id.seekbar); new AsynCallTask() { public void progress() throws InterruptedException{ for(int i=0;i<80;i++) { bar.setProgress(i); Thread.sleep(50); } } public void back() throws InterruptedException{ for(int i=bar.getProgress();i>0;i--) { bar.setProgress(i); Thread.sleep(50); } } public void showDialog(){ bar.post(new Runnable() { @Override public void run() { // TODO Auto-generated method stub AlertDialog.Builder builder = new Builder(StartActivity.this); builder.setMessage("发生了一个错误确认退出吗?"); builder.setTitle("询问用户"); builder.setPositiveButton("确认", new OnClickListener() { @Override public void onClick(DialogInterface d, int arg1) { // TODO Auto-generated method stub postExcute(2); } }); builder.create().show(); } }); } @Override protected boolean excute(int state) { // TODO Auto-generated method stub switch (state) { case 0: postStateByMethod("progress",1);//执行线程 break; case 1: postByMethod("showDialog");//错误提示 break; case 2: postStateByMethod("back",-1);//回滚 break; default: return false; } return true; } }; } }