java5线程池详解与Executors类创建不同线程池的用法

java中的线程池是非常重要的,它可以节省资源开销,从而提升程序的性能。向Tomcat等一些web服务器都必须用到线程池。java5中为我们提供了一些应用线程池的API,下面的代码将详解其用法。

package hxl.insist;

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

public class DifferentKindsThreadPool {

	public static void main(String[] args) {
		displayThreadPool();
		displayCachedThreadPool();
		displaySingleThreadPool();
		displayScheduledThreadPool();
	}

	/**
	 * 创建一个定时任务的线程池
	 */
	public static void displayScheduledThreadPool() {
		ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(4);
		//它可以向固定线程池一样执行任务
		distributeTaskForThreadPool(scheduledThreadPool);
		//这是它的特殊之处,可以定时任务
		scheduledThreadPool.schedule(
				new Runnable() {
					@Override
					public void run() {
						System.out.println("开始执行任务1");
					}
				},
				5,
				TimeUnit.SECONDS);
		//每隔2秒再次重新执行任务
		scheduledThreadPool.scheduleAtFixedRate(
				new Runnable() {
					@Override
					public void run() {
						System.out.println("开始执行任务2");
					}
				},
				5,
				3,
				TimeUnit.SECONDS);
	}

	/**
	 * 创建只有一个线程的线程池,如果线程终止,
	 * 他将会创建一个新的线程加入到池子中,这
	 * 个线程池会保证池子中始终有一个线程
	 */
	public static void displaySingleThreadPool() {
		ExecutorService singleThreadPool = Executors.newSingleThreadExecutor();
		distributeTaskForThreadPool(singleThreadPool);
	}

	/**
	 * 创建一个可根据需要创建线程的线程池,但是
	 * 当先前创建的线程可得到时就会重用先前的线
	 * 程,如果不存在可得到的线程,一个新的线程
	 * 将被创建并被加入到池子中。60秒没有被用到
	 * 的线程将被终止并从缓存中移除
	 */
	public static void displayCachedThreadPool() {
		ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
		distributeTaskForThreadPool(cachedThreadPool);
	}

	/**
	 * 创建一个带有固定线程的线程池
	 */
	public static void displayThreadPool() {
		// 创建一个带有4个固定线程的线程池
		ExecutorService threadPool = Executors.newFixedThreadPool(4);
		distributeTaskForThreadPool(threadPool);
	}

	/**
	 * 为线程池分配8个任务,使其驱动
	 * @param threadPool
	 */
	public static void distributeTaskForThreadPool(ExecutorService threadPool) {
		// 让线程池驱动8个任务
		for (int i = 1; i <= 8; i++) {
			// 由于内部类里面不能放一个非final的变量,所以我把i的值赋予task
			final int task = i;

			threadPool.execute(new Runnable() {
				@Override
				public void run() {
					System.out.println("我是" + Thread.currentThread().getName()
							+ "," + "拿到了第" + task + "个任务,我开始执行了");
				}
			});
		}
	}
}
时间: 2024-10-07 07:29:53

java5线程池详解与Executors类创建不同线程池的用法的相关文章

Java性能分析之线程栈详解(下)

Java性能分析之线程栈详解(下) 转载自:微信公众号"测试那点事儿" 结合jstack结果对线程状态详解 上篇文章详细介绍了线程栈的作用.状态.任何查看理解,本篇文章结合jstack工具来查看线程状态,并列出重点关注目标.Jstack是常用的排查工具,它能输出在某一个时间,Java进程中所有线程的状态,很多时候这些状态信息能给我们的排查工作带来有用的线索. Jstack的输出中,Java线程状态主要是以下几种: 1.BLOCKED 线程在等待monitor锁(synchronized

Java线程池详解(二)

一.前言 在总结了线程池的一些原理及实现细节之后,产出了一篇文章:Java线程池详解(一),后面的(一)是在本文出现之后加上的,而本文就成了(二).因为在写完第一篇关于java线程池的文章之后,越发觉得还有太多内容需要补充,每次都是修修补补,总觉得还缺点什么.在第一篇中,我着重描述了java线程池的原理以及它的实现,主要的点在于它是如何工作的.而本文的内容将更为上层,重点在于如何应用java线程池,算是对第一篇文章的一点补充,这样对于java线程池的学习和总结稍微完整一些. 使用过java线程池

java中的String类常量池详解

test1: package StringTest; public class test1 { /** * @param args */ public static void main(String[] args){ String a = "a1"; String b = "a"+ 1; System.out.println(a==b); }//true } test2: package StringTest; public class test2 { /** *

【java线程系列】java线程系列之java线程池详解

一线程池的概念及为何需要线程池: 我们知道当我们自己创建一个线程时如果该线程执行完任务后就进入死亡状态,这样如果我们需要在次使用一个线程时得重新创建一个线程,但是线程的创建是要付出一定的代价的,如果在我们的程序中需要频繁使用线程,且每个线程执行的时间很短,短到几乎小于线程创建及销毁的时间那么代价将会更大,如:服务器应用程序中经常出现的情况是:单个任务处理的时间很短而请求的数目却是巨大的.显然如果频繁的创建销毁线程效率将非常低. 那么我们能否让一个线程可以复用,即当一个线程执行完后不销毁该线程,而

Java线程池详解及实例

前言 多线程的异步执行方式,虽然能够最大限度发挥多核计算机的计算能力,但是如果不加控制,反而会对系统造成负担.线程本身也要占用内存空间,大量的线程会占用内存资源并且可能会导致Out of Memory.即便没有这样的情况,大量的线程回收也会给GC带来很大的压力. 为了避免重复的创建线程,线程池的出现可以让线程进行复用.通俗点讲,当有工作来,就会向线程池拿一个线程,当工作完成后,并不是直接关闭线程,而是将这个线程归还给线程池供其他任务使用. 接下来从总体到细致的方式,来共同探讨线程池. 总体的架构

线程池详解

管理一组线程集合,方便线程的复用,免了频繁创建和销毁线程所带来的开销,相关类的继承关系如下: Executor 仅声明了一个方法execute,代表要执行某个任务.ExecutorService 接口在其父类接口基础上,声明了包含但不限于shutdown.submit.invokeAll.invokeAny 等管理线程池的方法.ScheduledExecutorService 接口,则是声明了一些和定时任务相关的方法,比如 schedule和scheduleAtFixedRate.ThreadP

Java虚拟机原理图解 2.3、常量池详解(下)

[java] view plaincopyprint? package com.louis.jvm; public class Person { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public 

《Java虚拟机原理图解》 2.3、常量池详解(下)

NO9.类中引用到的field字段在常量池中是怎样描述的?(CONSTANT_Fieldref_info, CONSTANT_Name_Type_info) 一般而言,我们在定义类的过程中会定义一些 field 字段,然后会在这个类的其他地方(如方法中)使用到它.有可能我们在类的方法中只使用field字段一次,也有可能我们会在类定义的方法中使用它很多很多次. 举一个简单的例子,我们定一个叫Person的简单java bean,它有name和age两个field字段,如下所示: package c

Java 线程(多线程)详解

查看了许多书籍,网上的博客,现在我来说一下有关于我对线程的详解,有不对的欢迎指正. 一. 线程的生命周期: 程序有自己的一个生命周期,线程也不例外,也有自己的生命周期.查看许多书籍或者网上资料,发现了一件很有趣的事情,那就是它们对线程的生命周期不是唯一.有两种或者以上的线程生命周期. 第一种线程生命周期线程状态转换图:一共5个状态:新建,就绪,运行,阻塞和结束   图 1 第二种生命周期图:一共6个状态:New,Runnable,Blocked,Waiting,Timed Waiting,Ter