java四种线程池的简单解释及举例

使用线程池的原因是为了降低系统资源消耗,提高应用程序的性能和效率,若不使用线程池而总是启动新线程来执行多任务,会降低
系统资源的利用率。开启一个线程的代价是比较大的,开启线程并非只是消耗JVM资源,而且会面向系统申请资源。thread类的start0()
方法是个native方法,必然会由系统分配相关线程资源。
private native void start0();

因此引入线程池,提高系统资源利用率,java常用的四种线程池解释及使用如下:
1.CachedThreadPool
package test;

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


/**    官方释义:
     * Creates a thread pool that creates new threads as needed, but
     * will reuse previously constructed threads when they are
     * available.  These pools will typically improve the performance
     * of programs that execute many short-lived asynchronous tasks.
     * Calls to <tt>execute</tt> will reuse previously constructed
     * threads if available. If no existing thread is available, a new
     * thread will be created and added to the pool. Threads that have
     * not been used for sixty seconds are terminated and removed from
     * the cache. Thus, a pool that remains idle for long enough will
     * not consume any resources. Note that pools with similar
     * properties but different details (for example, timeout parameters)
     * may be created using {@link ThreadPoolExecutor} constructors.
     *
     * @return the newly created thread pool
     * 
     * 翻译(大致意思):创建一个应用程序需要多个线程的线程池,但是应用程序会重用之前构造的可用的
     * 空闲线程,它会显著的提升应用程序执行短耗时异步类型的任务。如果线程池中没有可用的线程,那
     * 么将会创建一个新线程并将其加入到线程池中。如果线程在60s内没有被使用,那么该线程将会被回收
     * 并且从缓存中移出,因此,该类型线程池会留存足够长的时间且不会消耗任何资源。
     * 
     * 
*/
public class CachedThreadPoolTest {
	public static void main(String[] args) throws InterruptedException {
		ExecutorService executor = Executors.newCachedThreadPool();
		for (int i = 0; i < 10; i++) {
			Thread.sleep(1000);
			executor.execute(new Runnable() {
				public void run() {
					String name = Thread.currentThread().getName();
					System.out.println("name" + name);
				}
			});
		}
		executor.shutdown();
	}
}

执行程序结果如下:
1处是第一个线程执行时的线程名为namepool-1-thread-1,启东第二线程时,休眠了1秒,此时第一个线程早已执行完成,
线程已经空出,所以第二个线程执行的时候依然使用的是第一个,因此线程名是相同的。
2.FixedThreadPool
package test;

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

/**
 * 官方释义:
 * Creates a thread pool that reuses a fixed number of threads
 * operating off a shared unbounded queue.  At any point, at most
 * <tt>nThreads</tt> threads will be active processing tasks.
 * If additional tasks are submitted when all threads are active,
 * they will wait in the queue until a thread is available.
 * If any thread terminates due to a failure during execution
 * prior to shutdown, a new one will take its place if needed to
 * execute subsequent tasks.  The threads in the pool will exist
 * until it is explicitly {@link ExecutorService#shutdown shutdown}.
 *
 * @param nThreads the number of threads in the pool
 * @return the newly created thread pool
 * @throws IllegalArgumentException if {@code nThreads <= 0}
 * 
 * 翻译(大致意思):创建一个固定数量的线程池,操作一个共享无边界的队列。任何时刻,最多只有
 * 指定数量的线程处理任务,如果当有额外的任务被提交到线程池但没有空闲线程可供使用时,则该
 * 任务会被放到队列中直到出现空闲线程,一旦有任一线程在执行完成前因失败而被终止,那么一个
 * 新的任务将会取代它进而执行后续的任务。
 * 
 */
public class FixedThreadPoolTest {
	private static int nThreads = 5;
	public static void main(String[] args) {
		ExecutorService executor = Executors.newFixedThreadPool(nThreads);
		for(int i=1;i<=10;i++){
			executor.submit(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					System.out.println("当前线程:"+Thread.currentThread().getName());
					try {
						Thread.sleep(5000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			});
		}
		executor.shutdown();
	}

}

执行程序首先打印如下信息:
因为线程池的初始化大小为5,但是开启了10个线程,所以实际上只开启了5个。由于没有可用的线程,所以程序阻塞,
直到5个线程允许完毕后,另外5个线程开始执行。
3.ScheduledThreadPool
package test;

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

/**
 * 
 * 周期性或定时执行任务
 *
 */
public class ScheduledThreadPoolTest {
	public static void main(String[] args) {
		//5表示线程池中保持5个线程,即使是空闲的。
		ScheduledExecutorService  ses = Executors.newScheduledThreadPool(5);
		ses.scheduleWithFixedDelay(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				System.out.println("hello world!!!");
				
			}
		}, 2, 3, TimeUnit.SECONDS);//2秒后执行,每隔3秒执行一次
//		ses.scheduleAtFixedRate(command, initialDelay, period, unit)
//		ses.schedule(callable, delay, unit)
//		ses.shutdown();
	}

}
如图:程序运行时,先过2秒打印"hello world!!!",然后每隔3秒打印一次"hello world!!!"
4.SingleThreadExecutorPool
package test;

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

/**
 * Creates an Executor that uses a single worker thread operating
 * off an unbounded queue. (Note however that if this single
 * thread terminates due to a failure during execution prior to
 * shutdown, a new one will take its place if needed to execute
 * subsequent tasks.)  Tasks are guaranteed to execute
 * sequentially, and no more than one task will be active at any
 * given time. Unlike the otherwise equivalent
 * <tt>newFixedThreadPool(1)</tt> the returned executor is
 * guaranteed not to be reconfigurable to use additional threads.
 *
 * @return the newly created single-threaded Executor
 * 
 * 创建一个单线程池操作共享队列,保证各个线程的执行顺序,和newFixedThreadPool(1)不同的
 * 是SingleThreadExecutorPool不会开启额外的线程。即线程的执行是有序的,
 */
public class SingleThreadExecutorPoolTest {
	public static void main(String[] args) {
		ExecutorService executor = Executors.newSingleThreadExecutor();
		for (int i = 0; i < 5; i++) {
            final int n = i;
			executor.submit(new Runnable() {
				@Override
				public void run() {
					// TODO Auto-generated method stub
					System.out.println("n====:"+n+",threadname:"+Thread.currentThread().getName());

				}
			});
		}
		executor.shutdown();
	}

}

执行结果如图:
各个线程是按顺序执行的且只使用一个线程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值