java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java的异步加载new Thread()

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

作者: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密集型(计算型)

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

线程池创建【使用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());
    }

任务执行流程

总结

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

您可能感兴趣的文章:
阅读全文