• 多线程手写Future模式


    future模式

    在进行耗时操作的时候,线程直接阻塞,我们需要优化这样的代码,让他再启动一个线程,不阻塞.可以执行下面的代码. 这个时候我们就用到了未来者模式

    future设计类

    只有一个方法 

    public interface Future<T> {
    
        T get() throws InterruptedException;
    
    }

    futureTask 类

    public interface FutureTask<T> {
    
        T call();
    
    }

    asyncFuture 类是fufure的实现类

    /**
     * @Created by xiaodao
     */
    public class AsynFuture<T> implements Future<T> {
    
        private volatile boolean done = true;
    
        private T result;
    
    
        public void done(T result){
            synchronized (this){
                this.result= result;
                this.done=false;
                this.notifyAll();
            }
    
        }
    
        @Override
        public T get() throws InterruptedException {
    
            synchronized (this){
                while (done){
                    this.wait();
                }
            }
            return result;
        }
    }

    FutureService 

      讲 fufure类 和futuretask类连接起来

    public class FutureService {
    
    
        public <T> Future<T> subimt(final FutureTask<T> task){
    
            AsynFuture<T> asynFuture= new AsynFuture();
    
            new Thread(()->{
                    T result = task.call();
                    asynFuture.done(result);
    
            }).start();
    
            return asynFuture;
        }
    
    
        public <T> Future<T> submit(final FutureTask<T> task, final Consumer<T> consumer) {
            AsynFuture<T> asynFuture = new AsynFuture<>();
            new Thread(() -> {
                T result = task.call();
                asynFuture.done(result);
                consumer.accept(result);
            }).start();
            return asynFuture;
        }
    
    
    }

    里面有俩种方法,一种是调用get的时候会阻塞,一种通过callable的方式回调回来,这样更加合理

    提供一个测试了类

    /**
     * Future        ->代表的是未来的一个凭据
     * FutureTask    ->将你的调用逻辑进行了隔离
     * FutureService ->桥接 Future和 FutureTask
     */
    public class SyncInvoker {
    
        public static void main(String[] args) throws InterruptedException {
    
            /**
             * 这种方式在调用的时候被阻塞住了.不好
             */
            FutureService futureService = new FutureService();
            Future<String> future = futureService.subimt(() -> {
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                return "FINISH";
            });
            /**
             * 不阻塞
             */
            futureService.submit(() -> {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
                return "FINISH-callable";
            },System.out::println);
            System.out.println(future.get());
            System.out.println("other thing .......");
    
            Thread.sleep(1000);
            System.out.println("==========");
    
        }
    
    }

    在调用的时候,就可以看到我们想要的效果,阻塞方式的话,会把主线程阻塞掉,非阻塞方式的话,不会当前进程会等的回调之后停止.

  • 相关阅读:
    LeetCode236. 二叉树的最近公共祖先
    LeetCode235. 二叉搜索树的最近公共祖先
    LeetCode第32场双周赛
    .NET+Vue 使用SignalR推送数据
    Asp.Net Core使用MongoDB
    CentOS8 部署SqlServer
    windows 任何软件出现异常有日志 w3wp.exe [10608]中发生了未处理的Microsoft .Net Framework异常
    C# Socket使用以及DotNetty和Supersocket 框架
    C# 数据结构与算法 操作系统原理 计算机网络原理 数据库开发学习
    DotNet .Net Framework与Net Core与Net Standard 以及.NET5
  • 原文地址:https://www.cnblogs.com/bj-xiaodao/p/10774661.html
Copyright © 2020-2023  润新知