java线程池——接收线程运行后返回的结果

java线程池——接收线程运行后返回的结果

java1.5新加入了线程同步的包。java.util.concurrent
其中有接口ExecutorService。
java线程池——接收线程运行后返回的结果_第1张图片

Executor提供了管理线程结束的方法,通过Future接口,能够跟踪一个或者多个异步线程运行的结果。
ExecutorService能够被shutdown,shutdown后,拒绝提交新的任务。ExecutorSerivce提供了两种shutdown的方式。shutdown()方法让先前已经提交的任务在终止操作前继续执行,而shutdownNow()方法阻止正在等待的线程启动,并且尝试终止当前正在运行的进程。终止线程后,Executor没有活跃的线程需要执行,也没有新的任务线程被提交。一个没有使用的ExecuteService应该被关闭,并且释放占用的资源。
Submit方法继承自Executor.execute(java.long.Runnable)方法,并且返回Future用来取消线程执行或者等待线程完成。invokeAny和invokeAll方法在执行大量线程时很常用。
Executors类提供了ExecutorService接口的工厂实现。

好,下面上货。
package com.xueyoucto.xueyou;

import java.util.concurrent.Callable;

public class ThreadReturnValue implements Callable {
    @Override
    public Object call() throws Exception {
        int temp = 0;
        StringBuffer sb = new StringBuffer("");
        synchronized (App.GLOBALARRAY) {
            for (int i = 0; i < App.GLOBALARRAY.length; i++) {
                System.out.println(Thread.currentThread().getName() + "\n" + App.GLOBALARRAY[i]);
                App.GLOBALARRAY[i] += 1;
                temp += App.GLOBALARRAY[i];
                sb.append("+").append(App.GLOBALARRAY[i]);
            }
        }
        return sb.toString() + "=" + temp;
    }
}

package com.xueyoucto.xueyou;


import java.util.concurrent.*;

/**
 * Hello world!
 */
public class App {
    public static int[] GLOBALARRAY = new int[50];

    public static ThreadLocal TLGLOBALARRAY = new ThreadLocal() {
        @Override
        protected String[] initialValue() {
            String[] temp = new String[50];
            for (int i = 0; i < temp.length; i++) {
                temp[i] = String.valueOf(i + 100);
            }
            return temp;
        }
    };

    static {
        for (int i = 0; i < GLOBALARRAY.length; i++) {
            GLOBALARRAY[i] = i;
        }
    }

    public static void main(String[] args) {
        ExecutorService pool = Executors.newFixedThreadPool(3);
        Future future = pool.submit(new ThreadReturnValue());
        Future future2 = pool.submit(new ThreadReturnValue());
        Future future3 = pool.submit(new ThreadReturnValue());
        pool.shutdown(); // 不允许再想线程池中增加线程
        //判断是否所有线程已经执行完毕
        try {
            boolean isFinish = pool.awaitTermination(1, TimeUnit.HOURS);
            System.out.println(isFinish + "==========================");
            //如果没有执行完
            if (!isFinish) {
                //线程池执行结束 不在等待线程执行完毕,直接执行下面的代码
                pool.shutdownNow();
            }
            String r = future.get();
            String r2 = future2.get();
            String r3 = future3.get();

            System.out.println(r);
            System.out.println(r2);
            System.out.println(r3);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        //只给线程池中的线程1小时,然后就继续执行
        System.out.println("it is ok !!!");
    }
}

运行结果:
java线程池——接收线程运行后返回的结果_第2张图片

需要注意的是ExecutorService提供的是线程池的功能,并没有提供线程同步、互斥等功能,所以还是需要在互斥访问的变量上进行处理的。下面是没有处理的代码和结果,可以对比一下。

package com.xueyoucto.xueyou;

import java.util.concurrent.Callable;

public class ThreadReturnValue implements Callable {
    @Override
    public Object call() throws Exception {
        int temp = 0;
        StringBuffer sb = new StringBuffer("");
        for (int i = 0; i < App.GLOBALARRAY.length; i++) {
            System.out.println(Thread.currentThread().getName() + "\n" + App.GLOBALARRAY[i]);
            App.GLOBALARRAY[i] += 1;
            temp += App.GLOBALARRAY[i];
            sb.append("+").append(App.GLOBALARRAY[i]);
        }
        return sb.toString() + "=" + temp;
    }
}

运行结果(注意最后的结果):
java线程池——接收线程运行后返回的结果_第3张图片


你可能感兴趣的:(java)