java线程池

Java线程池是一种管理和复用线程的机制,它通过在应用程序中维护一组工作线程,有效地管理并发任务的执行。线程池的主要目的是降低线程创建和销毁的开销,并提高程序性能。Java通过java.util.concurrent包提供了丰富的线程池支持,其中最常用的是ThreadPoolExecutor类。

import java.util.concurrent.*;

public class CustomThreadPoolExample {
    public static void main(String[] args) {
        int corePoolSize = 5;
        int maximumPoolSize = 10;
        long keepAliveTime = 5000;
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
        ExecutorService executorService = new ThreadPoolExecutor(
                corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS, workQueue);

        for (int i = 0; i < 10; i++) {
            final int taskNumber = i;
            executorService.submit(() -> {
                System.out.println("Task " + taskNumber + " executed by thread " + Thread.currentThread().getName());
            });
        }

        executorService.shutdown();
    }
}
import java.util.concurrent.*;

public class FutureExample {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(1);

        Callable<String> callableTask = () -> {
            Thread.sleep(2000);  // 模拟耗时任务
            return "Task completed";
        };

        Future<String> future = executorService.submit(callableTask);

        System.out.println("Main thread continues to do other work");

        try {
            // 阻塞,等待任务完成并获取结果
            String result = future.get();
            System.out.println("Task result: " + result);
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }

        executorService.shutdown();
    }
}

ThreadPoolExecutor的主要参数和组件:

  1. 核心线程数(corePoolSize):

    • 线程池中保持的最小线程数。
    • 在线程池创建后,即使线程处于空闲状态,也会一直存在,除非调用了allowCoreThreadTimeOut(true)
  2. 最大线程数(maximumPoolSize):

    • 线程池中允许的最大线程数。
    • 当工作队列满了且当前线程数小于最大线程数时,会创建新的线程执行任务。
  3. 线程存活时间(keepAliveTime)和时间单位(unit):

    • 在线程池中的空闲线程的最大存活时间。
    • 超过这个时间,空闲线程将被终止,直到线程数不超过核心线程数。
  4. 工作队列(workQueue):

    • 用于保存等待执行的任务的阻塞队列。
    • 常用的队列包括LinkedBlockingQueueArrayBlockingQueueSynchronousQueue等。     
  5. 线程工厂(threadFactory):

    • 用于创建新线程的工厂。
  6. 拒绝策略(RejectedExecutionHandler):

    • 当工作队列和线程池都满了,新任务无法被处理时的策略。
    • 常用的策略有AbortPolicyCallerRunsPolicyDiscardPolicy等。

线程池的生命周期:

  1. RUNNING:

    • 线程池处于正常运行状态。
  2. SHUTDOWN:

    • 不再接受新任务,但会处理队列中的任务。
  3. STOP:

    • 不再接受新任务,不再处理队列中的任务,同时会中断正在执行的任务。
  4. TIDYING:

    • 所有任务都已终止,workerCount为0,线程池将转到TIDYING状态。
  5. TERMINATED:

    • 在执行完terminated()钩子方法后,线程池最终将会达到TERMINATED状态。

 ThreadLocal

ThreadLocal是Java中用于在多线程环境下保持变量的线程局部副本的工具类。每个线程都可以独立地访问自己的副本,而不会影响其他线程的副本。这使得在多线程环境下能够方便地存储和获取线程私有的变量。

以下是ThreadLocal的基本使用方式:

public class ThreadLocalExample {
    private static final ThreadLocal<String> threadLocalVariable = new ThreadLocal<>();

    public static void main(String[] args) {
        // 在主线程设置ThreadLocal变量
        threadLocalVariable.set("Main Thread Value");

        // 创建并启动新线程
        Thread newThread = new Thread(() -> {
            // 在新线程中获取ThreadLocal变量
            String value = threadLocalVariable.get();
            System.out.println("New Thread Value: " + value);
        });

        newThread.start();
    }
}

在这个例子中,ThreadLocal对象被声明为静态的,可以在类的任何地方访问。在主线程中,通过set方法设置了一个字符串值。然后,创建了一个新线程,在新线程中通过get方法获取了ThreadLocal变量的值。由于每个线程都有自己的副本,所以修改一个线程的副本不会影响其他线程的副本。

ThreadLocal的一些注意事项:
  1. 初始值: 可以通过initialValue()方法或withInitial(Supplier)方法设置ThreadLocal的初始值。

    private static final ThreadLocal<String> threadLocalVariable = ThreadLocal.withInitial(() -> "Default Value");
    
  2. 内存泄漏:ThreadLocal不再被使用时,及时调用remove()方法以防止内存泄漏。threadLocalVariable.remove();

    threadLocalVariable.remove();
  3. 继承性:子线程会继承父线程的ThreadLocal变量。但在子线程中修改变量值不会影响父线程的副本,反之亦然。

  4. 避免共享:ThreadLocal主要用于在单个线程内共享变量,不建议将它用于线程间共享变量的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值