目录
在Java中,线程是用于执行程序中独立任务的执行单元。它允许多个任务同时执行,从而提高程序的并发性。线程池是线程的管理机制,它维护着一个线程集合,可以重复利用这些线程来执行多个任务。
1.继承Thread类:创建一个类继承自Thread类,并重写其run()方法,在该方法中定义线程要执行的任务。
public class MyThread extends Thread {
@Override
public void run() {
// 线程执行的任务逻辑
}
}
public class Main {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start(); // 启动线程
}
}
2.实现Runnable接口:创建一个类实现Runnable接口,并实现其中的run()方法,在该方法中定义线程要执行的任务。
public class MyRunnable implements Runnable {
????@Override
????public void run() {
????????// 线程执行的任务逻辑
????}
}
public class Main {
????public static void main(String[] args) {
????????MyRunnable runnable = new MyRunnable();
????????Thread thread = new Thread(runnable);
????????thread.start(); // 启动线程
????}
}
3.使用匿名内部类:通过创建一个继承Thread类或实现Runnable接口的匿名内部类,来定义线程要执行的任务。
public class Main {
????public static void main(String[] args) {
????????Thread thread = new Thread(new Runnable() {
????????????@Override
????????????public void run() {
????????????????// 线程执行的任务逻辑
????????????}
????????});
????????thread.start(); // 启动线程
????}
}
单线程的好处是简单易用,适用于一些简单的任务,不需要考虑线程之间的同步和协作。
然而,频繁使用单线程会导致程序的执行效率较低,因为任务需要按照顺序依次执行,无法利用多核处理器的优势。
提高性能:线程池可以重用线程,避免线程的频繁创建和销毁,从而节省系统资源。
提供线程管理和调度:线程池可以自动管理线程的生命周期,并提供线程的调度和监控功能。使用线程池时,一般情况下不需要手动关闭线程。线程池会自动管理线程的生命周期,并在任务执行完成后将线程释放回线程池以供重用。
控制并发度:线程池可以限制并发执行的线程数量,防止系统资源被过度占用。
核心线程数(corePoolSize):线程池中保持的常驻线程数量。
最大线程数(maximumPoolSize):线程池允许创建的最大线程数。
队列容量(workQueue):用于存放等待执行的任务的队列。
线程空闲时间(keepAliveTime):当线程池中线程数量超过核心线程数时,多余的空闲线程的存活时间。
线程工厂(threadFactory):用于创建新线程的工厂。
拒绝策略(rejectedExecutionHandler):当线程池和任务队列都满了,无法处理新的任务时,使用的策略。
创建线程池:通过ThreadPoolExecutor类的构造函数或Executors工具类提供的静态方法创建线程池。
提交任务:通过execute()方法提交任务给线程池执行。
关闭线程池:通过调用线程池的shutdown()或shutdownNow()方法来关闭线程池。
以下是简单的示例:
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExample {
public static void main(String[] args) {
// 创建线程池
ExecutorService executor = Executors.newFixedThreadPool(5);
// 提交任务给线程池执行
for (int i = 0; i < 10; i++) {
final int task = i;
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println("Task " + task + " is being executed.");
// 执行任务的逻辑代码
}
});
}
// 关闭线程池
executor.shutdown();
}
}
这里给大家提供一个可直接使用的线程池工具类
/**
* 线程池管理类(工具类)
*
*/
public class ThreadPoolManager {
/**
* 根据cpu的数量动态的配置核心线程数和最大线程数
*/
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
/**
* 核心线程数 = CPU核心数 + 1
* IO密集型:2CPU,计算密集型:CPU + 1
*/
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
/**
* 线程池最大线程数 = CPU核心数 * 2 + 1
*/
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
/**
* 非核心线程闲置时超时时间
*/
private static final int KEEP_ALIVE = 60;
/**
* 唯一实例
*/
public static ThreadPoolManager instance = newInstance();
/**
* 线程池的对象
*/
private ThreadPoolExecutor executor;
/**
* map:存储任务
*/
private Map<Long, Runnable> taskMap = new HashMap<Long, Runnable>();
/**
* 要确保该类只有一个实例对象,避免产生过多对象消费资源,所以采用单例模式
*/
private ThreadPoolManager() {
}
/**
* 获取实例
*
* @return 当前类实例
*/
private static ThreadPoolManager newInstance() {
ThreadPoolManager instance = new ThreadPoolManager();
instance.executor = instance.newPool();
return instance;
}
/**
* 新建线程池
* corePoolSize:核心线程数
* maximumPoolSize:线程池所容纳最大线程数(workQueue队列满了之后才开启)
* keepAliveTime:非核心线程闲置时间超时时长
* unit:keepAliveTime的单位
* workQueue:等待队列,存储还未执行的任务
* threadFactory:线程创建的工厂
* handler:异常处理机制
*
* @return 线程池
*/
private ThreadPoolExecutor newPool() {
return new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS,
new ArrayBlockingQueue<Runnable>(ThreadPoolConstants.THREAD_NUM),
CustomDefaultThreadFactory.newDefaultThreadFactory("MetaDataThreadPool"),
new ThreadPoolExecutor.AbortPolicy());
}
/**
* 开启一个无返回结果的线程
*
* @param r the r
*/
public void execute(Runnable r) {
// 把一个任务丢到了线程池中
executor.execute(r);
}
/**
* 开启一个无返回结果的线程
*
* @param taskId the task id
* @param r the r
*/
public void execute(Long taskId, Runnable r) {
// 把一个任务丢到了线程池中
executor.execute(r);
// 并加入map中
taskMap.put(taskId, r);
}
/**
* 开启一个有返回结果的线程
*
* @param <T> the type parameter
* @param r the r
* @return future future
*/
public <T> Future<T> submit(Callable<T> r) {
// 把一个任务丢到了线程池中
return executor.submit(r);
}
/**
* 通过jobPublish的id关闭线程
*
* @param id the id
*/
public void cancel(Long id) {
if (taskMap.containsKey(id)) {
if (taskMap.get(id) != null) {
executor.getQueue().remove(taskMap.get(id));
}
}
}
/**
* 把任务移除等待队列
*
* @param r the r
*/
public void cancel(Runnable r) {
if (r != null) {
executor.getQueue().remove(r);
}
}
}
使用示例:
ThreadPoolManager.instance.execute(new BaseRunnable() {
@Override
public void work() {
// 业务方法
}
});