Java并发编程二

来源:互联网 发布:直播app数据库设计 编辑:程序博客网 时间:2024/05/20 18:01

Java并发编程二(深入)

Runnable和Executor

​ 在Java中,Runnable接口描述一个你想运行的任务,通常和其他任务并行运行。

public interface Runnable{  void run();}

​ run方法中的代码将会在一个线程中执行。线程是执行一系列指令的机制,通常由操作系统提供。通过使用单独的处理器或者同一个处理器的不同时间片,多个线程并发运行。

​ 在实际中,让任务和线程之间维持一对一的关系通常是没有意义的。当任务执行只需要很短的时间时,你想在同一个线程上执行这些任务,不想浪费启动线程时间。当任务是计算密集型时,你就想让每个处理器只有一个线程,而不是每个任务一个线程,以避免线程之间切换的开销。

​ 在Java的并发类库中,executor执行任务,选择在哪个线程上执行任务。

Runnable task = ()->{...};            //声明了一个Runnable接口实例                                               //()->是一个lambda表达式Executor exec = ...;exec.execute(task);

​ Executor类有个工厂方法供不同类型executor的使用

调用exec = Executors.newCachedThreadPool();

​ 会产生一个有很多短暂的任务或者任务会消耗很多时间等待的程序优化过的executor。如果可能的话,每个任务在空闲的线程上执行;如果所有的线程都在繁忙工作,就会分配一个新线程。超过一定空闲时间的线程会被终止。

调用exec = Executors.newFixedThreadPool(nthreads);

​ 会产生一个数目固定的线程池。当你提交任务时,进行排队直到有可用的线程。对计算密集型任务,这是个不错的选择。你可以根据可用的处理器数目,推断出线程数。

Callable接口

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

​ 定义如下:

public interface Callable<V>{  V call() throws Exception;}

​ 与Runnable的区别如下:

  1. ​ Callable定义的方法是call,而Runnable定义的方法是run;
  2. ​ Callable的call方法可以有返回值,而Runnable的run方法不能有返回值;
  3. ​ Callable的call方法可以抛出异常。

Future和Executor服务

​ 要执行Callable,需要一个ExecutorService接口的实例,ExecutorService是Executor的子接口。Executor类的newCachedThreadPool和newFixedThreadPool方法能产生这样的对象。

ExecutorService exec =  Executors.newFixedThreadPool();Callable<V> task = ()->{...};Future<V> result = exec.submit(task);

​ 当你提交任务,你得到一个future——代表计算的对象,将来的某个时候会有可用的计算结果。