Callable接口实现Java多线程

2019-03-01 20:56|来源: 网络

Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。

Callable和Runnable有几点不同:

   (1)Callable规定的方法是call(),而Runnable规定的方法是run().

   (2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。

   (3)call()方法可抛出异常,而run()方法是不能抛出异常的.

   (4)运行Callable任务可拿到一个Future对象

       Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。  

       通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。

示例代码:
  1. import java.util.concurrent.Callable;    

  2. import java.util.concurrent.ExecutorService;    

  3. import java.util.concurrent.Executors;    

  4. import java.util.concurrent.Future;    

  5.    

  6. /** *//**  

  7. * Callable 和 Future接口  

  8. * Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它线程执行的任务。  

  9. * Callable和Runnable有几点不同:  

  10. * (1)Callable规定的方法是call(),而Runnable规定的方法是run().  

  11. * (2)Callable的任务执行后可返回值,而Runnable的任务是不能返回值的。  

  12. * (3)call()方法可抛出异常,而run()方法是不能抛出异常的。  

  13. * (4)运行Callable任务可拿到一个Future对象,  

  14. * Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。  

  15. * 通过Future对象可了解任务执行情况,可取消任务的执行,还可获取任务执行的结果。  

  16. */    

  17. public class CallableAndFuture {    

  18.    

  19.    /** *//**  

  20.     * 自定义一个任务类,实现Callable接口  

  21.     */    

  22.    public static class MyCallableClass implements Callable{    

  23.        // 标志位    

  24.        private int flag = 0;    

  25.        public MyCallableClass(int flag){    

  26.            this.flag = flag;    

  27.        }    

  28.        public String call() throws Exception{    

  29.            if (this.flag == 0){    

  30.                // 如果flag的值为0,则立即返回    

  31.                return "flag = 0";    

  32.            }      

  33.            if (this.flag == 1){    

  34.                // 如果flag的值为1,做一个无限循环    

  35.                try {    

  36.                    while (true) {    

  37.                        System.out.println("looping.");    

  38.                        Thread.sleep(2000);    

  39.                    }    

  40.                } catch (InterruptedException e) {    

  41.                    System.out.println("Interrupted");    

  42.                }    

  43.                return "false";    

  44.            } else {    

  45.                // falg不为0或者1,则抛出异常    

  46.                throw new Exception("Bad flag value!");    

  47.            }    

  48.        }    

  49.    }    

  50.        

  51.    public static void main(String[] args) {    

  52.        // 定义3个Callable类型的任务    

  53.        MyCallableClass task1 = new MyCallableClass(0);    

  54.        MyCallableClass task2 = new MyCallableClass(1);    

  55.        MyCallableClass task3 = new MyCallableClass(2);    

  56.            

  57.        // 创建一个执行任务的服务    

  58.        ExecutorService es = Executors.newFixedThreadPool(3);    

  59.        try {    

  60.            // 提交并执行任务,任务启动时返回了一个 Future对象,    

  61.            // 如果想得到任务执行的结果或者是异常可对这个Future对象进行操作    

  62.            Future future1 = es.submit(task1);    

  63.            // 获得第一个任务的结果,如果调用get方法,当前线程会等待任务执行完毕后才往下执行    

  64.            System.out.println("task1: " + future1.get());    

  65.                

  66.            Future future2 = es.submit(task2);    

  67.            // 等待5秒后,再停止第二个任务。因为第二个任务进行的是无限循环    

  68.            Thread.sleep(5000);    

  69.            System.out.println("task2 cancel: " + future2.cancel(true));    

  70.                

  71.            // 获取第三个任务的输出,因为执行第三个任务会引起异常    

  72.            // 所以下面的语句将引起异常的抛出    

  73.            Future future3 = es.submit(task3);    

  74.            System.out.println("task3: " + future3.get());    

  75.        } catch (Exception e){    

  76.            System.out.println(e.toString());    

  77.        }    

  78.        // 停止任务执行服务    

  79.        es.shutdownNow();    

  80.    }    

  81. }    



本文链接:Callable接口实现Java多线程,转自:http://aloys.iteye.com/blog/630135

相关问答

更多
  • Java多线程问题[2022-05-03]

    因为程序有等待。 比如你去查数据库,数据库返回数据之前会有一段等待时间,这段时间就可以执行其他的线程,这样就很快了。 其实一个cpu中,所有指令都是一条条执行的。
  • 用定时任务吧 quartz(时间粒度较细) ,Timer(java自带,比较简单) 教程百度吧 太多了
  • 举个面积的例子: 在java中,定义一个接口,声明计算长方形面积和周长的抽象方法,再用一个类去实现这个接口,再编写一个测试类去使用这个接口。 首先,接口必须单独存放,如果我们用eclipse编程的话,它们提示:The public type **** must be defined in its own file,意思是必须要定义在其自己的文件中,所以要为接口文件单独存放起来,举例,我们的接口要实现获到矩形的长,宽,面积,周长,所以定义以下的接口。 public interface calrect { pu ...
  • 用同步就行了
  • JAVA多线程编程[2022-03-08]

    多线程程序中,如您说的四线程,2个对一个变量加1,2个对一个变量减1,如果这个变量声明的时候加了synchronized关键字,那么这个变量同时只能有一个线程访问,其他的线程会排队,如果没加,那么可能出现同时操作一个变量的情况,举例来说,1个加的线程和一个减的线程同时对一个值为3的变量进行操作,可能的结果是4或2.
  • java多线程理解[2022-02-28]

    java语言已经内置了多线程支持,所有实现Runnable接口的类都可被启动一个新线程,新线程会执行该实例的run()方法,当run()方法执行完毕后,线程就结束了。 一旦一个线程执行完毕,这个实例就不能再重新启动,只能重新生成一个新实例,再启动一个新线程。 Thread类是实现了Runnable接口的一个实例,它代表一个线程的实例,并且,启动线程的唯一方法就是通过Thread类的start()实例方法: Thread t = new Thread(); t.start(); start()方法是一个nat ...
  • 在run方法里面 设置就可以了
  • 多线程的同步锁通过synchronized实现 有俩种方式 一种是在代码块加锁 代码块加锁时可以指定任意类的实例过的对象 即锁在这个对象上(任何对象都有一个锁) 使同一时间内只有一个线程可以访问到代码块中 另外一种就是以synchronized关键字修饰方法 这时加锁的对象就是类本身的实例 即this 以上 O(∩_∩)O
  • 在这里看到解释。 Callable接口类似于Runnable,因为它们都是为其实例可能被另一个线程执行的类设计的。 然而,Runnable不返回结果,也不能抛出被检查的异常。 See explanation here. The Callable interface is similar to Runnable, in that both are designed for classes whose instances are potentially executed by another thread. A ...
  • 根据我的评论,我相信你的问题是,在你的执行器服务中添加所有可调参数并调用它们之后,你还没有调用shutdown() 。 我建议你这样做: ExecutorService threadPool = Executors.newCachedThreadPool(); List> results = threadPool.invokeAll(tests); threadPool.shutdown(); // ******* add this! ********* 一旦所有可加密对象 ...