• FutureTask并发详解,通俗易懂


    最近做项目,使用到了FutureTask和主线程并发,应用到实际中还是挺实用的,特在此总结一下。

    有不对之处,忘各位多多指出。

     1 package com.demo;
     2 
     3 import java.util.concurrent.Callable;
     4 import java.util.concurrent.FutureTask;
     5 
     6 public class FutureTaskTest {
     7 
     8     public static void main(String[] args) throws Exception {
     9         for (int i = 0; i < 10; i++) {
    10             long currentTimeMillis = System.currentTimeMillis();
    11             FutureTask<String> future1 = new FutureTask<>(new MyTaskA());
    12             new Thread(future1).start();// 一定要先开启线程,如果主线程在开启线程前调用,就没了并发的效果,可以自行测试
    13             Thread.sleep(100);// 主线程耗时100ms
    14             String r1 = future1.get();
    15             System.out.println(r1);
    16             System.err.println(i + "-----" + String.valueOf(System.currentTimeMillis() - currentTimeMillis) + "ms");
    17         }
    18     }
    19 
    20     static class MyTaskA implements Callable<String> {
    21         @Override
    22         public String call() throws Exception {
    23             Thread.sleep(50);// 并发线程耗时50ms
    24             return "testA";
    25         }
    26     }
    27 
    28 }

    20-26行创建一个任务MyTaskA,实现的是Callable,主要是为了获取返回值(关于如何创建线程,这里就不在赘述);

    11行创建FutureTask;

    12行启动线程:此时任务MyTaskA就已经开始执行;

    13行主线程执行耗时100ms的任务;

    14行FutureTask获取返回值,该方法是会等待任务完成然后获取到返回值。

    输出结果如下:

    testA
    0-----101ms
    testA
    1-----100ms
    testA
    2-----100ms
    testA
    3-----100ms
    testA
    4-----100ms
    testA
    5-----100ms
    testA
    6-----100ms
    testA
    7-----100ms
    testA
    8-----100ms
    testA
    9-----100ms

    上面就是一个线程和主线程并发执行,下面再看一个两个线程和主线程并发,其实差别不大

     1 package com.demo;
     2 
     3 import java.util.concurrent.Callable;
     4 import java.util.concurrent.FutureTask;
     5 
     6 public class FutureTaskTest {
     7     
     8     public static void main(String[] args) throws Exception{
     9         for (int i = 0; i < 10; i++) {
    10             long currentTimeMillis = System.currentTimeMillis();
    11             
    12             FutureTask<String> futureA = new FutureTask<>(new MyTaskA()); 
    13             FutureTask<String> futureB = new FutureTask<>(new MyTaskB()); 
    14             new Thread(futureA).start();
    15             new Thread(futureB).start();
    16             
    17             Thread.sleep(100);
    18             System.out.println(futureA.get()+"---"+futureB.get());
    19             System.err.println(i+"-----"+String.valueOf(System.currentTimeMillis()-currentTimeMillis)+"ms");
    20         }
    21     }
    22     static class MyTaskA implements Callable<String>{
    23         @Override
    24         public String call() throws Exception {
    25             Thread.sleep(50);//并发线程耗时50ms
    26             return "testA";
    27         }
    28     }
    29     static class MyTaskB implements Callable<String>{
    30         @Override
    31         public String call() throws Exception {
    32             Thread.sleep(50);
    33             return "testB";
    34         }
    35     }
    36     
    37 
    38 }

    执行结果如下

    testA---testB
    0-----103ms
    testA---testB
    1-----100ms
    testA---testB
    2-----100ms
    testA---testB
    3-----100ms
    testA---testB
    4-----100ms
    testA---testB
    5-----101ms
    testA---testB
    6-----100ms
    testA---testB
    7-----101ms
    testA---testB
    8-----100ms
    testA---testB
    9-----101ms

    上面使用Thread启动的FutureTask,咱们也可以用线程池,代码如下

    package com.demo;
    
    import java.util.concurrent.Callable;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.Future;
    
    public class FutureTaskTest {
    
        public static void main(String[] args) throws Exception {
            for (int i = 0; i < 10; i++) {
                long currentTimeMillis = System.currentTimeMillis();
                ExecutorService executorService = Executors.newFixedThreadPool(2);
                Future<String> futureA = executorService.submit(new MyTaskA());
                Future<String> futureB = executorService.submit(new MyTaskB());
    
                Thread.sleep(100);
                System.out.println(futureA.get() + "---" + futureB.get());
                System.err.println(i + "-----" + String.valueOf(System.currentTimeMillis() - currentTimeMillis) + "ms");
           executorService.shutdown();//注意:用完之后一定要关闭线程池 } }
    static class MyTaskA implements Callable<String> { @Override public String call() throws Exception { Thread.sleep(50);// 并发线程耗时50ms return "testA"; } } static class MyTaskB implements Callable<String> { @Override public String call() throws Exception { Thread.sleep(50); return "testB"; } } }

    输出结果如下

    testA---testB
    0-----104ms
    testA---testB
    1-----101ms
    testA---testB
    2-----101ms
    testA---testB
    3-----101ms
    testA---testB
    4-----100ms
    testA---testB
    5-----102ms
    testA---testB
    6-----101ms
    testA---testB
    7-----101ms
    testA---testB
    8-----101ms
    testA---testB
    9-----101ms
  • 相关阅读:
    (2)javascript的基本语法、数据结构、变量
    (1)认识javascript
    CSS 浅析position:relative/absolute定位方式
    jquery实现下拉框多选
    Vue.js not detected
    手机代理调试Charles Proxy和Fiddler
    render函数之jsx应用
    vue组件通信方式(多种方案)
    点击页面空白处地方,隐藏弹窗
    css圆角不圆和1px方案
  • 原文地址:https://www.cnblogs.com/java-spring/p/8664427.html
Copyright © 2020-2023  润新知