线程池小结2

Posted 陈驰字新宇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了线程池小结2相关的知识,希望对你有一定的参考价值。

关于线程池的介绍,请看上一篇博客:http://www.cnblogs.com/DarrenChan/p/5774921.html

1. 线程池的5中创建方式

1) Single Thread Executor : 只有一个线程的线程池,因此所有提交的任务是顺序执行,

代码: Executors.newSingleThreadExecutor()

2) Cached Thread Pool : 线程池里有很多线程需要同时执行,老的可用线程将被新的任务触发重新执行,如果线程超过60秒内没执行,那么将被终止并从池中删除,

代码:Executors.newCachedThreadPool()

3) Fixed Thread Pool : 拥有固定线程数的线程池,如果没有任务执行,那么线程会一直等待,

代码: Executors.newFixedThreadPool(4)

在构造函数中的参数4是线程池的大小,你可以随意设置,也可以和cpu的核数量保持一致,获取cpu的核数量int cpuNums = Runtime.getRuntime().availableProcessors();

4) Scheduled Thread Pool : 用来调度即将执行的任务的线程池,可能是不是直接执行, 每隔多久执行一次... 策略型的

代码:Executors.newScheduledThreadPool()

5) Single Thread Scheduled Pool : 只有一个线程,用来调度任务在指定时间执行,代码:Executors.newSingleThreadScheduledExecutor()

使用代码小结:

package cn.itcast_01_mythread.pool;

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

/**
 * 列出并发包中的各种线程池
 * @author
 *
 */

public class ExecutorDemo {
    
    public static void main(String[] args) {
        ExecutorService newSingleThreadExecutor = Executors.newSingleThreadExecutor();
        ExecutorService newCachedThreadPool = Executors.newCachedThreadPool();
        
        int cpuNums = Runtime.getRuntime().availableProcessors();//电脑的核心数
        System.out.println(cpuNums);
        ExecutorService newFixedThreadPool = Executors.newFixedThreadPool(cpuNums);
        ScheduledExecutorService newScheduledThreadPool = Executors.newScheduledThreadPool(8);
        
        ScheduledExecutorService newSingleThreadScheduledExecutor = Executors.newSingleThreadScheduledExecutor();
    }
}

 

 

2. 线程池的使用

1)提交 Runnable ,任务完成后 Future 对象返回 null

调用submit,提交任务, 匿名Runable重写run方法, run方法里是业务逻辑(调用execute()提交任务也可以)

package cn.itcast_01_mythread.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.submit(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();
    }

}

运行结果:

thread name: pool-1-thread-1
thread name: pool-1-thread-5
thread name: pool-1-thread-3
thread name: pool-1-thread-2
thread name: pool-1-thread-4

 

2) 提交 Callable,该方法返回一个 Future 实例表示任务的状态

调用submit提交任务, 匿名Callable,重写call方法, 有返回值, 获取返回值会阻塞,一直要等到线程任务返回结果

调用submit提交任务,有Future返回值,里面可以传Callable对象或者Runnable对象

package cn.itcast_01_mythread.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);

        for (int i = 0; i < 10; i++) {
            Future<String> submit = pool.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    // System.out.println("a");
                    Thread.sleep(5000);
                    return "b--" + Thread.currentThread().getName();
                }
            });
            // 从Future中get结果,这个方法是会被阻塞的,一直要等到线程任务返回结果
            System.out.println(submit.get());
        }
        pool.shutdown();

    }

}

运行结果:

b--pool-1-thread-1
b--pool-1-thread-2
b--pool-1-thread-3
b--pool-1-thread-4
b--pool-1-thread-1
b--pool-1-thread-2
b--pool-1-thread-3
b--pool-1-thread-4
b--pool-1-thread-1
b--pool-1-thread-2

 

 

 

再观察一个简单例子:

TaskRunnable.java:

package cn.itcast_01_mythread.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);
        
    }

}

 

TaskCallable.java:

package cn.itcast_01_mythread.pool;

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

public class TaskCallable implements Callable<String> {

    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 + "";
    }

}

 

TestPool.java:

package cn.itcast_01_mythread.pool;

import java.util.ArrayList;
import java.util.Random;
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<Future<?>> results = new ArrayList<Future<?>>();
        
        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?"已完成":"未完成")+"====线程返回future结果: " + f.get());
        }
        exec.shutdown();
    }
}

 

运行结果:

pool-1-thread-1 启动时间:1489198939
pool-1-thread-1 is working...4
pool-1-thread-4 启动时间:1489198942
pool-1-thread-3 启动时间:1489198943
pool-1-thread-4 is working...5
pool-1-thread-2 启动时间:1489198945
pool-1-thread-4 启动时间:1489198945
pool-1-thread-1 启动时间:1489198945
pool-1-thread-4 is working...6
pool-1-thread-3 is working...8
pool-1-thread-1 is working...3
pool-1-thread-4 启动时间:1489198946
pool-1-thread-4 is working...2
pool-1-thread-2 is working...1
pool-1-thread-3 启动时间:1489198947
pool-1-thread-3 is working...7
pool-1-thread-1 启动时间:1489198948
pool-1-thread-1 is working...0
pool-1-thread-4 启动时间:1489198948
未完成====线程返回future结果: 0
已完成====线程返回future结果: 1
已完成====线程返回future结果: 2
已完成====线程返回future结果: 3
已完成====线程返回future结果: 4
已完成====线程返回future结果: 5
已完成====线程返回future结果: 6
已完成====线程返回future结果: 7
已完成====线程返回future结果: 8
pool-1-thread-4 is working...9
未完成====线程返回future结果: 9

 

以上是关于线程池小结2的主要内容,如果未能解决你的问题,请参考以下文章

Java线程池监控小结

JAVA 线程与线程池简单小结

线程池知识小结

线程池之小结

Java Executors小结

IDEA对新建java线程池的建议