多线程之----------线程池

以前项目中没用到过线程池,今天偶然有人问起就研究了下:

首先在JDK6.0中提供了线程池的方法:

ThreadPoolExecutor类

一个 ExecutorService,它使用可能的几个池线程之一执行每个提交的任务,通常使用 Executors 工厂方法配置。

线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行任务集时使用的线程)的方法。每个 ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数。

为了便于跨大量上下文使用,此类提供了很多可调整的参数和扩展钩子 (hook)。但是,强烈建议程序员使用较为方便的 Executors 工厂方法Executors.newCachedThreadPool()(无界线程池,可以进行自动线程回收)、Executors.newFixedThreadPool(int)(固定大小线程池)和Executors.newSingleThreadExecutor()(单个后台线程),它们均为大多数使用场景预定义了设置。

使用ExecutorService threadPool=Executors.newCachedThreadPool();实现线程池

1.新建一个线程方法:

package com.dava;

import java.util.Random;

public class MyThread extends Thread {
    //标记运行的是哪个线程 private int i; public MyThread(int i) { this.i = i; } @Override public void run() { System.out.println("线程开始执行..." + i); try { //线程处理时,暂停 sleep(new Random().nextInt(1000)); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程结束执行..." + i); } }

  2.调用线程

package com.dava;

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

public class ThreadRun{
    
    
    public static void main(String[] args) {
        //线程池
        ExecutorService threadPool=Executors.newCachedThreadPool();
        MyThread mt1=new MyThread(1);
        MyThread mt2=new MyThread(2);
        MyThread mt3=new MyThread(3);
        MyThread mt4=new MyThread(4);
        MyThread mt5=new MyThread(5);
        MyThread mt6=new MyThread(6);
        MyThread mt7=new MyThread(7);
        MyThread mt8=new MyThread(8);
        MyThread mt9=new MyThread(9);
        MyThread mt10=new MyThread(10);
        
        threadPool.execute(mt1);
        threadPool.execute(mt2);
        threadPool.execute(mt3);
        threadPool.execute(mt4);
        threadPool.execute(mt5);
        threadPool.execute(mt6);
        threadPool.execute(mt7);
        threadPool.execute(mt8);
        threadPool.execute(mt9);
        threadPool.execute(mt10);

threadPool.shutdown(); } }

运行结果:

线程开始执行...4
线程开始执行...3
线程开始执行...5
线程开始执行...1
线程开始执行...2
线程开始执行...7
线程开始执行...6
线程开始执行...8
线程开始执行...9
线程开始执行...10
线程结束执行...7
线程结束执行...4
线程结束执行...10
线程结束执行...2
线程结束执行...6
线程结束执行...3
线程结束执行...9
线程结束执行...1
线程结束执行...8
线程结束执行...5

每个线程等待随机时间,用于判断线程任务所需时间。

如何统计线程某一个时刻完成数目呢?

可以使用如下方法:

((ThreadPoolExecutor) threadPool).getCompletedTaskCount()

整体方法为:

package com.dava;

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

public class ThreadRun{
    
    
    public static void main(String[] args) {
        //线程池
        ExecutorService threadPool=Executors.newCachedThreadPool();
        MyThread mt1=new MyThread(1);
        MyThread mt2=new MyThread(2);
        MyThread mt3=new MyThread(3);
        MyThread mt4=new MyThread(4);
        MyThread mt5=new MyThread(5);
        MyThread mt6=new MyThread(6);
        MyThread mt7=new MyThread(7);
        MyThread mt8=new MyThread(8);
        MyThread mt9=new MyThread(9);
        MyThread mt10=new MyThread(10);
        
        threadPool.execute(mt1);
        threadPool.execute(mt2);
        threadPool.execute(mt3);
        threadPool.execute(mt4);
        threadPool.execute(mt5);
        threadPool.execute(mt6);
        threadPool.execute(mt7);
        threadPool.execute(mt8);
        threadPool.execute(mt9);
        threadPool.execute(mt10);
        
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(((ThreadPoolExecutor) threadPool).getCompletedTaskCount());
        
        threadPool.shutdown();
    }
}

运行结果为:

线程开始执行...2
线程开始执行...6
线程开始执行...10
线程开始执行...1
线程开始执行...3
线程开始执行...4
线程开始执行...5
线程开始执行...7
线程开始执行...8
线程开始执行...9
线程结束执行...1
1
线程结束执行...3
线程结束执行...10
线程结束执行...9
线程结束执行...5
线程结束执行...6
线程结束执行...2
线程结束执行...7
线程结束执行...8
线程结束执行...4

end;

原文地址:https://www.cnblogs.com/dava/p/6548386.html