java多线程之线程池(ExecutorService)

墨蓝 2022-05-17 13:20 380阅读 0赞
  1. 创建新线程的服务器在创建和销毁线程上花费的时间和消耗的系统资源要比花在处理实际的用户请求的时间和资源更多,线程池为线程生命周期开销问题和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。 其好处是,因为在请求到达时线程已经存在,所以无意中也消除了线程创建所带来的 延迟。这样,就可以立即为请求服务,使应用程序响应更快。而且,通过适当地调整 线程池中的线程数目,也就是当请求的数目超过某个阈值时,就强制其它任何新到的请求一直等待,直到获得一个线程来处理为止,从而可以防止资源不足。

示例代码:

ThreadPoolTest类:

  1. public class ThreadPoolTest {
  2. //单一线程数:就是只有一个线程开启,如果多长执行的话就是,这个线程一直轮询执行下去
  3. @SuppressWarnings("unused")
  4. private ExecutorService executorService1 = Executors.newSingleThreadExecutor();
  5. //固定线程数:在程序初始化的时候,虚拟机初始化5个线程
  6. @SuppressWarnings("unused")
  7. private ExecutorService executorService2 = Executors.newFixedThreadPool(5);
  8. //缓存线程数:在程序初始化的时候创建5线程线程,并随着系统的需求增加线程数量,线程数量的上限是系统资源的上线
  9. private ExecutorService executorService3 = Executors.newScheduledThreadPool(5);
  10. private static int num = 50;
  11. public void threadPool() throws InterruptedException {
  12. //创建了50个线程
  13. for(int i = 0; i < 50; i ++) {
  14. executorService3.execute(new Runnable() {
  15. public void run() {
  16. try {
  17. Thread.sleep(new Random().nextInt(1700));
  18. } catch (InterruptedException e) {
  19. // TODO Auto-generated catch block
  20. e.printStackTrace();
  21. }
  22. finish();
  23. System.out.println(Thread.currentThread().getName() + "当前剩余任务数量:" + (num));
  24. }
  25. });
  26. }
  27. }
  28. public synchronized void finish() {
  29. num--;
  30. if(num == 0) {
  31. System.out.println("线程池所有任务执行完毕");
  32. }
  33. }
  34. }

Main类:

  1. public class Main {
  2. public static void main(String[] args) throws Exception {
  3. System.out.println("-----------threadPool测试-----------------");
  4. new ThreadPoolTest().threadPool();
  5. }

测试结果:

70

可以看到5个线程在执行50个任务,只要线程池里有空闲线程,就会使该线程执行任务。

另外,还可以通过实现Runnable接口,使用线程池ExecutorService的submit方法来向线程池提交任务。

示例代码:

ThreadPoolSubmit类:

  1. public class ThreadPoolSubmit implements Runnable{
  2. private static int num = 50;
  3. public void run() {
  4. try {
  5. Thread.sleep(new Random().nextInt(1700));
  6. } catch (InterruptedException e) {
  7. // TODO Auto-generated catch block
  8. e.printStackTrace();
  9. }
  10. finish();
  11. System.out.println(Thread.currentThread().getName() + "当前剩余任务数量:" + (num));
  12. }
  13. public synchronized void finish() {
  14. num--;
  15. if(num == 0) {
  16. System.out.println("线程池所有任务执行完毕");
  17. }
  18. }
  19. public static void main(String[] args) {
  20. ExecutorService executorService = Executors.newScheduledThreadPool(5);
  21. //50个任务
  22. for (int i = 0; i < 50; i++) {
  23. executorService.submit(new ThreadPoolSubmit());
  24. }
  25. }
  26. }

测试结果与上例相同。

发表评论

表情:
评论列表 (有 0 条评论,380人围观)

还没有评论,来说两句吧...

相关阅读

    相关 java线线

    java多线程之线程池 池化技术 程序的运行,其本质上,是对系统资源(CPU、内存、磁盘、网络等等)的使用。如何高效的使用这些资源是我们编程优化演进的一个方向。今天说

    相关 java ExecutorService 线

    最近在做项目时,需要用到线程池。 我不喜欢一开始上来就讲底层,因为这样子很深奥。 对于线程池,java jdk 1.7里会有对应的接口ExecutorService与实现类

    相关 java线线ExecutorService

           创建新线程的服务器在创建和销毁线程上花费的时间和消耗的系统资源要比花在处理实际的用户请求的时间和资源更多,线程池为线程生命周期开销问题和资源不足问题提供了解决方案