• Java中实现多线程关键词整理


    Java中的Runable,Callable,Future,FutureTask,ExecutorService,Excetor,Excutors,ThreadPoolExcetor在这里对这些关键词,以及它们的用法做一个总结。

    首先将它们分个类:
    Runable,Callable
    Future,FutureTask
    ExecutorService,Executor,Excutors,ThreadPoolExcetor

    1. 关于Ranable和Callable
      --
      首先Java中创建线程的方法有三种:
    2. 继承Thread类,覆盖run方法
    3. 实现Runable接口,实现run方法
    4. 实现Callable接口,实现run方法

    三种实现的优缺点:

    1. 继承Thread,单继承的缘故,不能再继承其他类,获取当前线程this
    2. 实现Runable接口,没有返回值,获取当前线程Thread.currentThread()
    3. 实现Callable接口,可通过Future.get()获取返回值,获取当前线程 Thread.currentThread()

    继承Thread,两个步骤:

    class DemoThread extends Thread {
        @Override
        public void run() {
            super.run();
            // Perform time-consuming operation...
        }
    }
    DemoThread t = new DemoThread();
    t.start();
    
    • 继承Thread类,覆盖run()方法。
    • 创建线程对象并用start()方法启动线程。

    实现Runable,一般使用如下:

    new Thread(new Runnable() {
        @Override
        public void run() {
            // do something
        }
    }).start();
    

    为了简单。
    以上两种方式获取线程执行的结果相当麻烦,不能直接获取。JDK1.5增加了 Callable, Callable 的 call() 方法可以返回值和抛出异常。Callable 可以返回装载有计算结果的 Future 对象。
    Callable的源码:

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

    Callable的基本使用方法:

    FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() {
        @Override
        public Integer call() throws Exception {
            // do something
            return null;
        }
    });
    Thread thread = new Thread(futureTask);
    thread.start();
    Integer result = futureTask.get();
    

    运行 Callable 任务可以拿到一个 Future 对象,通过Future的get()方法拿到线程执行的返回值。那么...Future,FutureTask区别是什么,怎么使用?
    ->next()

    1. 关于Future和FutureTask
      --
      为了获取线程的执行结果,引入了Future的FutureTask,那么他们是什么关系,如何使用?
      Future类位于java.util.concurrent包下,它是一个接口:
    public interface Future<V> {
        boolean cancel(boolean mayInterruptIfRunning);
        boolean isCancelled();
        boolean isDone();
        V get() throws InterruptedException, ExecutionException;
        V get(long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException;
    }
    

    Future 定义了5个方法:

    1. boolean cancel(boolean mayInterruptIfRunning):试图取消对此任务的执行。如果任务已完成、或已取消,或者由于某些其他原因而无法取消,则此尝试将失败。当调用 cancel() 时,如果调用成功,而此任务尚未启动,则此任务将永不运行。如果任务已经启动,则 mayInterruptIfRunning 参数确定是否应该以试图停止任务的方式来中断执行此任务的线程。此方法返回后,对 isDone() 的后续调用将始终返回 true。如果此方法返回 true,则对 isCancelled() 的后续调用将始终返回 true。
    2. boolean isCancelled():如果在任务正常完成前将其取消,则返回 true。
    3. boolean isDone():如果任务已完成,则返回 true。 可能由于正常终止、异常或取消而完成,在所有这些情况中,此方法都将返回 true。
    4. V get()throws InterruptedException,ExecutionException:如有必要,等待计算完成,然后获取其结果。
    5. V get(long timeout,TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException: 如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)。

    总的来说Future提供了三种功能:

    1. 判断任务是否完成;
    2. 能够中断任务;
    3. 能够获取任务执行结果。

    重点
    RunnableFuture继承了Runnable接口和Future接口,而FutureTask实现了RunnableFuture接口。
    FutureTask的实现:

    public class FutureTask<V> implements RunnableFuture<V>
    

    RunnableFuture接口的实现:

    public interface RunnableFuture<V> extends Runnable, Future<V> {
        void run();
    }
    

    FutureTask是Future接口的一个唯一实现类。
    除了可以用Thread包装FutureTask外,还有另一种使用方法:

    ExecutorService executor = Executors.newCachedThreadPool();
    FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() {
        @Override
        public Integer call() throws Exception {
            // do something
            return null;
        }
    });
    executor.submit(futureTask);
    Integer result = futureTask.get();
    

    这里用到了Executor 框架。
    ->next();

    1. 关于ExecutorService,Executor,Excutors,ThreadPoolExcetor
      --
      Executor框架在Java 5中被引入,Executor 框架是一个根据一组执行策略调用、调度、执行和控制的异步任务的框架。
      在说Executor 框架之前我们需要引入一个新的概念——线程池(ThreadPoolExecutor):
    public ThreadPoolExecutor(intcorePoolSize,
            int maximumPoolSize,
            long keepAliveTime,
            TimeUnit unit,
            BlockingQueue<Runnable> workQueue,
            ThreadFactory threadFactory,
            RejectedExecutionHandler handler)
    

    ThreadPoolExecutor是Executors类的底层实现。
    在JDK帮助文档中,有如此一段话:

    “强烈建议程序员使用较为方便的 Executors 工厂方法 Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)、Executors.newFixedThreadPool(int)(固定大小线程池)和 Executors.newSingleThreadExecutor()(单个后台线程),它们均为大多数使用场景预定义了设置。”

    那么ExecutorService,Excetor,Excutors都是什么?
    Excetor是一个抽象层面的核心接口:

    public interface Executor {
        void execute(Runnable command);
    }
    

    ExecutorService 接口 对 Executor 接口进行了扩展,提供了返回 Future 对象,终止,关闭线程池等方法。

    public interface ExecutorService extends Executor {
    	void shutdown();
    	<T> Future<T> submit(Callable<T> task);
    	<T> Future<T> submit(Runnable task, T result);
    	<T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit) throws InterruptedException;
    }
    

    Executors 是一个工具类,类似于 Collections。提供工厂方法来创建不同类型的线程池,比如 FixedThreadPool 或 CachedThreadPool。

    public class Executors {
        public static ExecutorService newFixedThreadPool(int nThreads) {
            return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());
            }
            
         public static ExecutorService newCachedThreadPool() {
            return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>());
            }
    }
    

    以上是对Java多线程关键词的整理,不至于一团乱麻。

  • 相关阅读:
    Ubuntu搭建flask服务器, 部署sklearn 机器学习模型
    Jupyter-notebook 显示图片的两种方法
    Linux多版本opencv指定 & CMake中 find_package()的原理解析
    使用C++调用pytorch模型(Linux)
    Arch / Manjaro Linux下 Opencv 编译 配置 查看
    获取路径下所有特定格式文件列表
    Pycharm相对路径
    opencv 与操作 bitwise_and
    vim学习
    opencv 旋转 点旋转 以及 逆旋转
  • 原文地址:https://www.cnblogs.com/aheizi/p/6843399.html
Copyright © 2020-2023  润新知