zoukankan      html  css  js  c++  java
  • Callable和futrue、ExecutorService的用法

    首先说明是为了解决什么问题?

    为了解决主线程无谓等待浪费服务器资源的问题。当主线程执行一个费时的操作时,比如客户端发起一个请求,该请求在服务器端处理很复杂,如需要调用其他系统的接口,总之比较耗时。这时主线程一直等待的话比较浪费资源,所以需要创建一个子线程单独处理而同时主线程又可以处理其他的任务,不会一直无谓的等待。


    1.callable是干什么用的?

       callable用来创建子线程。和常见的Runnable和Thread实现的区别是  callable可以返回执行完的结果,其他两个不能。

    2.futrue是什么用的?

       futrue用来监听callable的执行情况,只要做三个事情:1.获取执行完的结果,2.监听是否执行完(是否取消),3.终止线程。

    3.ExecutorService线程池干什么用的?

       管理线程callable,如开始一个线程。

    第一个方法:submit提交一个实现Callable接口的任务,并且返回封装了异步计算结果的Future。
    第二个方法:submit提交一个实现Runnable接口的任务,并且指定了在调用Future的get方法时返回的result对象。
    第三个方法:submit提交一个实现Runnable接口的任务,并且返回封装了异步计算结果的Future。
    因此我们只要创建好我们的线程对象(实现Callable接口或者Runnable接口),然后通过上面3个方法提交给线程池去执行即可。还有点要注意的是,除了我们自己实现Callable对象外,我们还可以使用工厂类Executors来把一个Runnable对象包装成Callable对象。Executors工厂类提供的方法如下:
    Student stu=new Student();
    //Student 实现callable接口,重写call方法
    
    //实现1
    ExecutorService execute=Executors.newSingleThreadExecutor();
    Future<Object> future=execute.submit(stu);
    
    //2
    FutureTask<Object> future=new FutureTask<Object>(stu);
    execute.submit(future);
    

      Student 类

    package Clone;
    
    import java.util.concurrent.Callable;
    
    public class Student implements Callable<Object>{
    
    	private String name;
    	private int score;
    	public String getName() {
    		return name;
    	}
    	public void setName(String name) {
    		this.name = name;
    	}
    	public int getScore() {
    		return score;
    	}
    	public void setScore(int score) throws InterruptedException {
    		this.score = score;
    	}
    	
    	
    	@Override
    	public Object call() throws Exception {
    		System.out.println("开始执行");
    		String str="";
    		for(int i=0;i<10000;i++){
    			str=str+i+";";
    		}
    		Thread.sleep(6000);
    		System.err.println("执行完成"+str);
    		setName(str);
    		return str;
    	}
    	
    	
    }
    

      看完整代码演示:

    package Clone;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutionException;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    import java.util.concurrent.FutureTask;
    import java.util.concurrent.TimeUnit;
    
    
    public class testCallable {
    	public static void main(String[] args) throws InterruptedException, ExecutionException {
    		Student stu=new Student();
    		ExecutorService execute=Executors.newSingleThreadExecutor();
    		//Future<Object> future=execute.submit(stu);
    		
    		FutureTask<Object> future=new FutureTask<Object>(stu);
    		execute.submit(future);
    		
    		try {
    			    isWait(future);
    				System.out.println("取得执行结果"+future.get());
    			
    		} catch (Exception e) {
    			System.out.println("出现异常!!!");
    		}
    		System.out.println("执行其他任务");
    		execute.shutdown();
    	}
    	
    	public static boolean isWait(Future future) throws InterruptedException{
    		if(!future.isDone()){
    			Thread.sleep(2000);
    			System.out.println("再等一秒");
    			isWait(future);
    		}
    		return future.isDone();
    	}
    }
    

      运行结果:

    可以看到主线程并没有在这一行execute.submit(future);阻塞,而是继续往下执行代码,并且可以是否执行完。

    更多详细用法参考:http://blog.csdn.net/javazejian/article/details/50896505

  • 相关阅读:
    MySQL中各数据类型的取值范围
    解决方法:访问接口 "SQLNCLI10" 的架构行集 "DBSCHEMA_TABLES_INFO"。该访问接口支持该接口
    mysql中数据类型N
    有点想鸟
    了解 Microsoft Access 安全性
    用Delphi编写ASP的ActiveX
    用Delphi制作DLL的方法
    功自诚在,利从义来
    手把手教delphi:写你的dll文件--因为想帮兄弟写个dll,把原来压箱底的东东翻出来,快作完了,但要测试先
    还是有一点点累
  • 原文地址:https://www.cnblogs.com/wangzhuxing/p/8228881.html
Copyright © 2011-2022 走看看