Java中concurrent包中线程池的使用

Java中concurrent包中线程池的使用

Sample1 通过Runable提交任务

一个Runable就是一个任务。

ThreadPoolWithRunable.java

package com.mrbcy.bigdata.basic.thread.pool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ThreadPoolWithRunable {


    /**
     * 通过线程池执行线程
     * @param args
     */
    public static void main(String[] args) {
        //创建一个线程池
        ExecutorService pool = Executors.newCachedThreadPool();
        for(int i = 0; i < 5; i++){
            pool.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println("thread name: " + Thread.currentThread().getName());
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        pool.shutdown();
    }

}

Sample2 通过Callable和Future提交任务

package com.mrbcy.bigdata.basic.thread.pool;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
 * callable 跟runnable的区别:
 * runnable的run方法不会有任何返回结果,所以主线程无法获得任务线程的返回值
 * 
 * callable的call方法可以返回结果,但是主线程在获取时是被阻塞,需要等待任务线程返回才能拿到结果
 * @author
 *
 */
public class ThreadPoolWithcallable {

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        ExecutorService pool = Executors.newFixedThreadPool(4); 
        List> futures = new ArrayList>();

        for(int i = 0; i < 10; i++){
            Future submit = pool.submit(new Callable(){
                @Override
                public String call() throws Exception {
                    //System.out.println("a");
                    Thread.sleep(5000);
                    return "b--"+Thread.currentThread().getName();
                }              
               });
            futures.add(submit);

        } 
        for(Future future : futures){
            //从Future中get结果,这个方法是会被阻塞的,一直要等到线程任务返回结果
            System.out.println(future.get());
        }
        pool.shutdown();

    }

}

除非外面的线程确实知道任务线程的处理结果,否则不要用Future的get方法,避免阻塞主线程。

Sample3 综合例子

TestPool.java

package com.mrbcy.bigdata.basic.thread.pool;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;


public class TestPool {

    public static void main(String[] args) throws Exception {
        Future submit = null;
        Random random = new Random();

        //创建固定数量线程池
//      ExecutorService exec = Executors.newFixedThreadPool(4);

        //创建调度线程池
        ScheduledExecutorService exec = Executors.newScheduledThreadPool(4);

        //用来记录各线程的返回结果
        ArrayList> results = new ArrayList>();

        for (int i = 0; i < 10; i++) {
            //fixedPool提交线程,runnable无返回值,callable有返回值
            /*submit = exec.submit(new TaskRunnable(i));*/
            /*submit = exec.submit(new TaskCallable(i));*/

            //对于schedulerPool来说,调用submit提交任务时,跟普通pool效果一致
//          submit = exec.submit(new TaskCallable(i));
            //对于schedulerPool来说,调用schedule提交任务时,则可按延迟,按间隔时长来调度线程的运行
            submit = exec.schedule(new TaskCallable(i), random.nextInt(10), TimeUnit.SECONDS);
            //存储线程执行结果
            results.add(submit);

        }


        //打印结果
        for(Future f: results){
            boolean done = f.isDone();
            System.out.println(done?"已完成":"未完成");  //从结果的打印顺序可以看到,即使未完成,也会阻塞等待
            System.out.println("线程返回future结果: " + f.get());
        }

        exec.shutdown();

    }
}

TaskCallable.java

package com.mrbcy.bigdata.basic.thread.pool;

import java.util.Random;
import java.util.concurrent.Callable;

public class TaskCallable implements Callable{

    private int s;
    Random r = new Random();
    public TaskCallable(int s){
        this.s = s;
    }

    @Override
    public String call() throws Exception {
        String name = Thread.currentThread().getName();
        long currentTimeMillis = System.currentTimeMillis();
        System.out.println(name+" 启动时间:" + currentTimeMillis/1000);

        int rint = r.nextInt(3);
        try {
            Thread.sleep(rint*1000);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
        System.out.println(name + " is working..."+s);
        return s+"";
    }

}

TaskRunnable.java

package com.mrbcy.bigdata.basic.thread.pool;

import java.util.Random;

public class TaskRunnable implements Runnable{
    private int s;

    public TaskRunnable(int s){
        this.s = s;
    }

    Random r = new Random();

    @Override
    public void run() {
        String name = Thread.currentThread().getName();
        long currentTimeMillis = System.currentTimeMillis();
        System.out.println(name+" 启动时间:" + currentTimeMillis/1000);

        int rint = r.nextInt(3);
        try {
            Thread.sleep(rint*1000);
        } catch (InterruptedException e) {

            e.printStackTrace();
        }
        System.out.println(name + " is working..."+s);

    }

}

你可能感兴趣的:(Java基础)