java中的异步加载new Thread()方式

 更新时间:2023年08月28日 16:13:50   作者:TJkaklf  
这篇文章主要介绍了java中的异步加载new Thread()方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

java的异步加载new Thread()

public class LoginInterface{
   public String delSession(){
    new Thread(new Runnable() { @Override public void run() { //需要执行的代码 } }).start();
   }}

使用匿名内部类编译

class LoginInterface$1
  implements Runnable
{
  LoginInterface$1(LoginInterface paramLoginInterface, String paramString)
  {
  }
  public void run()
  {
//要执行的代码
  }
}

聊聊new Thread()的危害

危害

1)开销大

每次new Thread() 都会创建新的对象,开销较大,无法复用增加垃圾回收的负担。

2)管理困难

每个new Thread() 都是独立的个体,无法有效的管控,无限制创建相互竞争,可能导致oom或者核心业务线程阻塞。

3)功能单一

无法定时执行,中断线程等功能。

线程池

1)复用已创建的线程,减少对象创建、消亡的开销,性能佳。

2)可控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞。

3)可定时执行、中断线程等功能。

线程池大小

1)CPU密集型(计算型)

  • 使用较小的线程池,一般是Cpu核心数+1
  • 因为CPU密集型任务CPU的使用率很高,若开过多的线程,只能增加线程上下文的切换次数,带来额外的开销

2)IO密集型(查询访问型)

  • 使用较大的线程池,一般CPU核心数 * 2
  • 因为IO密集型CPU使用率不高,可以让CPU等待IO的时候处理别的任务,充分利用cpu时间

线程池创建【使用ThreadPoolExecutor手动创建】

public class CommonThreadPool {
    /**
     * 线程池对象
     */
    public static ExecutorService pool = null;
    /**
     * 线程池核心池的大小
     */
    private static final int CORE_POOL_SIZE = 5;
    /**
     * 获取当前系统的CPU 数目
     */
    private static int cpuNums = Runtime.getRuntime().availableProcessors();
    /**
     * 线程池的最大线程数
     */
    private static final int MAX_POOL_SIZE = (cpuNums * 2) > CORE_POOL_SIZE ? (cpuNums * 2) : CORE_POOL_SIZE;
    static {
        pool = new ThreadPoolExecutor(
                CORE_POOL_SIZE,             // 核心线程数
                MAX_POOL_SIZE,              // 最大线程数 通常核心线程数=最大线程数 当MAX_POOL_SIZE > CORE_POOL_SIZE 时,并不是当核心线程全部被占用后立马开始创建新的线程(只有在队列也满了之后才会开始新建线程)
                0L,            // 存活时间   >=0 0 永不回收【非核心线程除外】
                TimeUnit.MILLISECONDS,      // 单位
                new ArrayBlockingQueue<Runnable>(100),                          // 队列 存放待执行任务
                new ThreadFactoryBuilder().setNameFormat("CommonThread-%d").build(),    // 创建工厂
                new ThreadPoolExecutor.AbortPolicy());                                  // 拒绝策略 默认拒绝 丢弃 丢弃最老的 主线程执行
    }
}

禁用Executors创建线程池

1)Executors屏蔽的线程池的内部实现细节,开发人员需要根据服务器情况与业务场景定义更合适的线程池。

2)newFixedThreadPool 和 newSingleThreadExecutor的主要问题是堆积的请求处理队列可能会耗费非常大的内存,甚至 OOM。

    public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

3)newCachedThreadPool 和 newScheduledThreadPool:主要问题是线程数最大数是 Integer.MAX_VALUE,可能会创建数量非常多的线程,甚至 OOM。

    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    public ScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,
              new DelayedWorkQueue());
    }
  • LinkedBlockingQueue:队列默认大小Integer.MAX_VALUE,未指定大小时可以视为无界队列。
  • SynchronousQueue:队列大容量为0,不存储任何数据。
  • DelayedWorkQueue:无界,队列顺序按照延时时长排序。

任务执行流程

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Java实现的微信公众号获取微信用户信息示例

    Java实现的微信公众号获取微信用户信息示例

    这篇文章主要介绍了Java实现的微信公众号获取微信用户信息,结合实例形式分析了Java微信公众号获取微信用户信息相关原理、步骤与操作注意事项,需要的朋友可以参考下
    2019-10-10
  • Spring Boot自动配置源码实例解析

    Spring Boot自动配置源码实例解析

    Spring Boot作为Java领域最为流行的快速开发框架之一,其核心特性之一就是其强大的自动配置机制,下面这篇文章主要给大家介绍了关于Spring Boot自动配置源码的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-08-08
  • 选择java的理由:java之父访谈实录

    选择java的理由:java之父访谈实录

    选择java的理由:java之父访谈实录...
    2006-12-12
  • OAuth2生成token代码备忘实现过程示例

    OAuth2生成token代码备忘实现过程示例

    这篇文章主要为大家介绍了OAuth2生成token代码备忘实现过程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-08-08
  • 详解Java中的线程池

    详解Java中的线程池

    这篇文章主要介绍了Java中的线程池,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • 教你用JAVA写文本编辑器(四)

    教你用JAVA写文本编辑器(四)

    这篇文章主要给大家介绍了关于用JAVA写文本编辑器的相关资料,通过这篇文章你可以完整的知道利用JAVA写文本编辑器的完整过程,需要的朋友可以参考下
    2021-11-11
  • Spring中的事务管理实例详解

    Spring中的事务管理实例详解

    这篇文章主要介绍了Spring中的事务管理,以实例形式详细分析了事务的概念与特性以及事物管理的具体用法,需要的朋友可以参考下
    2014-11-11
  • java如何删除以逗号隔开的字符串中某一个值

    java如何删除以逗号隔开的字符串中某一个值

    这篇文章主要介绍了java如何删除以逗号隔开的字符串中某一个值,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06
  • java中的数学计算函数的总结

    java中的数学计算函数的总结

    这篇文章主要介绍了java中的数学计算函数的总结的相关资料,需要的朋友可以参考下
    2017-07-07
  • Java实现字符串的分割(基于String.split()方法)

    Java实现字符串的分割(基于String.split()方法)

    Java中的我们可以利用split把字符串按照指定的分割符进行分割,然后返回字符串数组,下面这篇文章主要给大家介绍了关于Java实现字符串的分割的相关资料,是基于jDK1.8版本中的String.split()方法,需要的朋友可以参考下
    2022-09-09

最新评论