服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服务器之家 - 编程语言 - JAVA教程 - Java编程中线程池的基本概念和使用

Java编程中线程池的基本概念和使用

2020-01-20 11:35goldensun JAVA教程

这篇文章主要介绍了Java编程中线程池的基本概念和使用,多线程编程是使Java程序实现并发的一个重要手段,需要的朋友可以参考下

1 引入线程池的原因
  由于线程的生命周期中包括创建、就绪、运行、阻塞、销毁阶段,当我们待处理的任务数目较小时,我们可以自己创建几个线程来处理相应的任务,但当有大量的任务时,由于创建、销毁线程需要很大的开销,运用线程池这些问题就大大的缓解了。

2 线程池的使用
  我们只需要运用Executors类给我们提供的静态方法,就可以创建相应的线程池:

?
1
2
3
4
5
public static ExecutorSevice newSingleThreadExecutor()
 
public static ExecutorSevice newFixedThreadPool()
 
public static ExecutorSevice newCachedThreadPool()

  newSingleThreadExecutor返回以个包含单线程的Executor,将多个任务交给此Exector时,这个线程处理完一个任务后接着处理下一个任务,若该线程出现异常,将会有一个新的线程来替代。

  newFixedThreadPool返回一个包含指定数目线程的线程池,如果任务数量多于线程数目,那么没有没有执行的任务必须等待,直到有任务完成为止。

  newCachedThreadPool根据用户的任务数创建相应的线程来处理,该线程池不会对线程数目加以限制,完全依赖于JVM能创建线程的数量,可能引起内存不足。

  我们只需要将待执行的任务放入run方法中即可,将Runnable接口的实现类交给线程池的execute方法,作为它的一个参数,如下所示:

?
1
2
3
4
5
6
Executor executor = Executors.newSingleThreadExecutor();
executor.execute(new Runnable(){
  public void run(){
    //执行的任务 
 }
}

  如果需要给任务传递参数,可以通过创建一个Runnable接口的实现类来完成。

3.实例
(1):newSingleThreadExecutor
MyThread.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
publicclassMyThread extends Thread {
  @Override
  publicvoid run() {
    System.out.println(Thread.currentThread().getName() + "正在执行。。。");
  }
}
TestSingleThreadExecutor.java
publicclassTestSingleThreadExecutor {
  publicstaticvoid main(String[] args) {
    //创建一个可重用固定线程数的线程池
    ExecutorService pool = Executors. newSingleThreadExecutor();
    //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
    Thread t1 = new MyThread();
    Thread t2 = new MyThread();
    Thread t3 = new MyThread();
    Thread t4 = new MyThread();
    Thread t5 = new MyThread();
    //将线程放入池中进行执行
    pool.execute(t1);
    pool.execute(t2);
    pool.execute(t3);
    pool.execute(t4);
    pool.execute(t5);
    //关闭线程池
    pool.shutdown();
  }
}

输出结果

?
1
2
3
4
5
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-1正在执行。。。

(2):newFixedThreadPool
TestFixedThreadPool.Java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
publicclass TestFixedThreadPool {
  publicstaticvoid main(String[] args) {
    //创建一个可重用固定线程数的线程池
    ExecutorService pool = Executors.newFixedThreadPool(2);
    //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
    Thread t1 = new MyThread();
    Thread t2 = new MyThread();
    Thread t3 = new MyThread();
    Thread t4 = new MyThread();
    Thread t5 = new MyThread();
    //将线程放入池中进行执行
    pool.execute(t1);
    pool.execute(t2);
    pool.execute(t3);
    pool.execute(t4);
    pool.execute(t5);
    //关闭线程池
    pool.shutdown();
  }
}

输出结果

?
1
2
3
4
5
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-2正在执行。。。
pool-1-thread-1正在执行。。。

(3): newCachedThreadPool
TestCachedThreadPool.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
publicclass TestCachedThreadPool {
  publicstaticvoid main(String[] args) {
    //创建一个可重用固定线程数的线程池
    ExecutorService pool = Executors.newCachedThreadPool();
    //创建实现了Runnable接口对象,Thread对象当然也实现了Runnable接口
    Thread t1 = new MyThread();
    Thread t2 = new MyThread();
    Thread t3 = new MyThread();
    Thread t4 = new MyThread();
    Thread t5 = new MyThread();
    //将线程放入池中进行执行
    pool.execute(t1);
    pool.execute(t2);
    pool.execute(t3);
    pool.execute(t4);
    pool.execute(t5);
    //关闭线程池
    pool.shutdown();
  }
}

输出结果:

?
1
2
3
4
5
pool-1-thread-2正在执行。。。
pool-1-thread-4正在执行。。。
pool-1-thread-3正在执行。。。
pool-1-thread-1正在执行。。。
pool-1-thread-5正在执行。。。

(4):newScheduledThreadPool
TestScheduledThreadPoolExecutor.java

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
publicclass TestScheduledThreadPoolExecutor {
  publicstaticvoid main(String[] args) {
    ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1);
    exec.scheduleAtFixedRate(new Runnable() {//每隔一段时间就触发异常
           @Override
           publicvoid run() {
              //throw new RuntimeException();
              System.out.println("================");
           }
         }, 1000, 5000, TimeUnit.MILLISECONDS);
    exec.scheduleAtFixedRate(new Runnable() {//每隔一段时间打印系统时间,证明两者是互不影响的
           @Override
           publicvoid run() {
              System.out.println(System.nanoTime());
           }
         }, 1000, 2000, TimeUnit.MILLISECONDS);
  }
}

输出结果

?
1
2
3
4
5
6
7
8
================
8384644549516
8386643829034
8388643830710
================
8390643851383
8392643879319
8400643939383

延伸 · 阅读

精彩推荐
  • JAVA教程Java 连接Access数据库的两种方式

    Java 连接Access数据库的两种方式

    这篇文章主要介绍了Java 连接Access数据库的两种方式,本文着重讲解使用JDBC连接操作Access数据库,需要的朋友可以参考下 ...

    junjie5072019-12-24
  • JAVA教程java泛型学习示例

    java泛型学习示例

    Java泛型(Generics)是JDK5开始引入的一个新特性,允许在定义类和接口的时候使用类型参数(Type Parameter)。下面是学习泛型的示例 ...

    Java教程网2192019-11-21
  • JAVA教程Java实现Linux下双守护进程

    Java实现Linux下双守护进程

    这篇文章主要介绍了Java实现Linux下双守护进程的思路、原理以及具体实现方式,非常的详细,希望对大家有所帮助 ...

    hebedich3122019-12-03
  • JAVA教程java IO流文件的读写具体实例

    java IO流文件的读写具体实例

    这篇文章主要介绍了java IO流文件的读写具体实例,有需要的朋友可以参考一下 ...

    java教程网4202019-10-25
  • JAVA教程java实现八皇后问题示例分享

    java实现八皇后问题示例分享

    这篇文章主要介绍了java实现八皇后问题示例,八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于...

    java教程网1842019-11-14
  • JAVA教程实例讲解Java并发编程之闭锁

    实例讲解Java并发编程之闭锁

    这篇文章主要介绍了实例讲解Java并发编程之闭锁,闭锁相当于一扇门,在闭锁到达结束状态之前,这扇门一直是关闭着的,没有任何线程可以通过,当到达结束状...

    junjie2642019-12-16
  • JAVA教程java stringbuffer的用法示例

    java stringbuffer的用法示例

    这篇文章主要介绍了java stringbuffer的用法示例,字符串缓冲区,是一个容器(当返回到的是String时而且长度不确定,数据类型不确定时就可以用StringBuffer)其...

    java教程网1282019-10-31
  • JAVA教程java字符串比较获取字符串出现次数的示例

    java字符串比较获取字符串出现次数的示例

    java获取一个字符串在整个字符串出现的次数,下面写出我的思路和二个实现方法,大家参考使用吧 ...

    java教程网4842019-10-30