Java多线程Thread , Future , Callable , FutureTask的使用

 更新时间:2024年04月30日 09:41:33   作者:perfecto1  
本文主要介绍了Java多线程Thread , Future , Callable , FutureTask的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

 Thread创建一个线程

在想要使用多线程的技术来进行相应的操作的时候: 可以含有以下的方向来进行设计思考! 在创建一个线程的时候通常是创建一个Thread的。 但是这个Thread,是含有多种方式来进行创建操作的。 例如: 直接使用空参数的构造器进行创建操作:

        System.out.println("start:" + System.currentTimeMillis());
        Thread thread = new Thread();
        thread.start();
        System.out.println("end:" + System.currentTimeMillis());

这样执行是没有什么效果的。这种情况就是你启动了一个线程,但是这个线程是没有任何事情要干的。

时间是过的飞起的。

但是还有一种方法也是可以进行线程的启动操作的。

使用含有参数方法的构造器进行创建线程:

System.out.println(Thread.currentThread() + "----start:" + System.currentTimeMillis());
Thread thread = new Thread(new Runnable() {
    @Override
    public void run() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("我正在执行一个任务,不要打扰我!");
        System.out.println(Thread.currentThread());
    }
});
thread.start();
System.out.println(Thread.currentThread() + "----end:" + System.currentTimeMillis());

这种是开启一个线程让其来进行线程任务的执行操作的。

但是你有没有发现,这种方式有一点缺点的。

这个开启的线程是相当于我要让其进行一些子任务的执行操作的。

Thread进行异步处理

类似于我是老师,我想让学习委员去办公室帮我拿一些书来的。此时学习委员已经出发了,但是我想起来我好像是带了书的。我想要让学习委员不要去办公室拿书了。

若我直接采用这种方式来来进行执行操作的话,是无法满足我的需求的。只要是我叫他去拿书了,她就会喊不回来的。

那是否能对这种方式进行相应的改造操作呢???

java的开发者是给了我们一种实现的方式的。

使用Future的接口满足需求。

相应的解释:

A Future 表示异步计算的结果。提供了用于检查计算是否完成、等待计算完成以及检索计算结果的方法。只有在计算完成后才能使用方法 get 检索结果,必要时会阻止,直到它准备就绪。取消是通过该 cancel 方法执行的。提供了其他方法来确定任务是正常完成还是已取消。计算完成后,无法取消计算。如果为了可取消性而使用 a Future ,但不提供可用的结果,则可以声明表单 Future<?> 的类型,并作为基础任务的结果返回 null 。

public interface Future<V> {
​
    /**
     * Attempts to cancel execution of this task.  This attempt will
     * fail if the task has already completed, has already been cancelled,
     * or could not be cancelled for some other reason. If successful,
     * and this task has not started when {@code cancel} is called,
     * this task should never run.  If the task has already started,
     * then the {@code mayInterruptIfRunning} parameter determines
     * whether the thread executing this task should be interrupted in
     * an attempt to stop the task.
     *
     * <p>After this method returns, subsequent calls to {@link #isDone} will
     * always return {@code true}.  Subsequent calls to {@link #isCancelled}
     * will always return {@code true} if this method returned {@code true}.
     *
     * @param mayInterruptIfRunning {@code true} if the thread executing this
     * task should be interrupted; otherwise, in-progress tasks are allowed
     * to complete
     * @return {@code false} if the task could not be cancelled,
     * typically because it has already completed normally;
     * {@code true} otherwise
     */
    boolean cancel(boolean mayInterruptIfRunning);
​
    /**
     * Returns {@code true} if this task was cancelled before it completed
     * normally.
     *
     * @return {@code true} if this task was cancelled before it completed
     */
    boolean isCancelled();
​
    /**
     * Returns {@code true} if this task completed.
     *
     * Completion may be due to normal termination, an exception, or
     * cancellation -- in all of these cases, this method will return
     * {@code true}.
     *
     * @return {@code true} if this task completed
     */
    boolean isDone();
​
    /**
     * Waits if necessary for the computation to complete, and then
     * retrieves its result.
     *
     * @return the computed result
     * @throws CancellationException if the computation was cancelled
     * @throws ExecutionException if the computation threw an
     * exception
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     */
    V get() throws InterruptedException, ExecutionException;
​
    /**
     * Waits if necessary for at most the given time for the computation
     * to complete, and then retrieves its result, if available.
     *
     * @param timeout the maximum time to wait
     * @param unit the time unit of the timeout argument
     * @return the computed result
     * @throws CancellationException if the computation was cancelled
     * @throws ExecutionException if the computation threw an
     * exception
     * @throws InterruptedException if the current thread was interrupted
     * while waiting
     * @throws TimeoutException if the wait timed out
     */
    V get(long timeout, TimeUnit unit)
        throws InterruptedException, ExecutionException, TimeoutException;
}

通过这个接口就可以实现相对应的功能操作了。

给予了一个接口想要将其进行实现操作就得要相关的实现类。

登场的就是FutureTask的类进行操作的。

public FutureTask(Runnable runnable, V result) {
    this.callable = Executors.callable(runnable, result);
    this.state = NEW;       // ensure visibility of callable
}

执行一下相关的代码:

 FutureTask<String> stringFutureTask = new FutureTask<String>(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("我正在执行一个任务,不要打扰我!");
                System.out.println(Thread.currentThread());
            }
        } , null);
​
        Thread futureThread = new Thread(stringFutureTask);
        futureThread.start();
//      是可以满足对一个进行任务的取消工作的
//        stringFutureTask.cancel(true);
        System.out.println(stringFutureTask.isCancelled());
​
​
        Thread futureThread1 = new Thread(stringFutureTask);
        futureThread1.start();

第二个 futureThread1 是不会执行的。

解释原因:

在Java中,FutureTask只能执行一次。当您尝试第二次执行相同的FutureTask实例时,它不会执行任何操作。这是因为FutureTask的状态在第一次执行后会改变,它不会重新开始。如果第一个线程(futureThread)已经开始执行stringFutureTask,那么第二个线程(futureThread1)尝试开始相同的stringFutureTask时,将不会有任何效果,因为FutureTask的状态已经不是初始状态了。

这里是一些关键点:

  • FutureTask在执行后会进入完成状态。

  • 如果尝试再次执行一个已经完成的FutureTask,它不会重新执行。

  • 如果需要重新执行任务,您需要创建一个新的FutureTask实例。

上面相关的例子,已经将一个老师叫学习委员去办公室拿书的例子叫停了。也就是说现在是实现了异步处理的操作。

带有参数的返回线程处理

我现在还有一个需求,是干嘛的呢???我不是喊学习委员去办公室拿书了吗??我想要那个他拿到的书给我手上。这个功能是怎么实现的呢?

也就是含有返回值的相关的例子!!!

JUC给了一个方法,是可以直接将一个Callable的接口传过来的

public FutureTask(Callable<V> callable) {
    if (callable == null)
        throw new NullPointerException();
    this.callable = callable;
    this.state = NEW;       // ensure visibility of callable
}

使用这个接口作为参数传给的FutureTask进行任务的初始化操作。

我们知道Callable接口是有返回值的。那么就可以类似于得到相应的那一本书了!!!

操作实现:

    FutureTask<String> stringFutureTask = new FutureTask<String>(new Callable<String>() {
        @Override
        public String call() throws Exception {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("我正在执行一个任务,不要打扰我!");
            return "老师,我拿到书了";
        }
    });
​
    Thread thread = new Thread(stringFutureTask);
    thread.start();
    System.out.println(stringFutureTask.get());

将得到的东西进行返回操作。这样的话就可以实现三种基本的功能操作了。

到此这篇关于Java多线程Thread , Future , Callable , FutureTask的使用的文章就介绍到这了,更多相关Java Thread , Future , Callable , FutureTask内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Springboot集成ProtoBuf的实例

    Springboot集成ProtoBuf的实例

    这篇文章主要介绍了Springboot集成ProtoBuf的实例,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • SpringBoot打包发布到linux上(centos 7)的步骤

    SpringBoot打包发布到linux上(centos 7)的步骤

    这篇文章主要介绍了SpringBoot打包发布到linux上(centos 7)的步骤,帮助大家更好的理解和使用springboot框架,感兴趣的朋友可以了解下
    2020-12-12
  • springmvc集成shiro登录权限示例代码

    springmvc集成shiro登录权限示例代码

    本篇文章主要介绍了springmvc集成shiro登录权限示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • Java深入了解数据结构之优先级队列(堆)

    Java深入了解数据结构之优先级队列(堆)

    普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (first in, largest out)的行为特征。通常采用堆数据结构来实现
    2022-01-01
  • Java 线程对比(Thread,Runnable,Callable)实例详解

    Java 线程对比(Thread,Runnable,Callable)实例详解

    这篇文章主要介绍了Java 线程(Thread,Runnable,Callable)实例详解的相关资料,这里对java 线程的三种方法进行了对比,需要的朋友可以参考下
    2016-12-12
  • Java中byte输出write到文件的实现方法讲解

    Java中byte输出write到文件的实现方法讲解

    今天小编就为大家分享一篇关于Java中byte输出write到文件的实现方法讲解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Java 对称加密几种算法分别实现

    Java 对称加密几种算法分别实现

    这篇文章主要介绍了Java 对称加密使用DES / 3DES / AES 这三种算法分别实现的相关资料,这里提供了实例代码,需要的朋友可以参考下
    2017-01-01
  • jvm内存溢出解决方法(jvm内存溢出怎么解决)

    jvm内存溢出解决方法(jvm内存溢出怎么解决)

    jvm内存溢出解决方法,详细内容看下面解释
    2013-12-12
  • 详解基于MybatisPlus两步实现多租户方案

    详解基于MybatisPlus两步实现多租户方案

    这篇文章主要介绍了详解基于MybatisPlus两步实现多租户方案,本文分两步,通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • C++实现扫雷游戏示例讲解

    C++实现扫雷游戏示例讲解

    这篇文章主要介绍了C++实现扫雷游戏示例讲解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08

最新评论