面试今典-Java中线程池-线程池用法分析

113 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第3天,点击查看活动详情

分析一下线程池的使用 非常简单

public class FixedThreadPoolTest {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(1);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("需要一个runnable");
            }
        };
        //向线程池种提交任务
        threadPool.execute(
                //这个地方的代码等同与上面的runnable 实现类 Java8新特性
                ()->{
            System.out.println("需要一个runnable");
        });
        
    }
}

模拟OutOfMemoryError异常抛出

  • 当 JVM 内存严重不足时,就会抛出 java.lang.OutOfMemoryError 错误。本文总结了常见的 OOM 原因及其解决方法。如有遗漏或错误

image.png

上代码:

public class FixedThreadPoolTest {
    public static void main(String[] args) {
        ExecutorService threadPool = Executors.newFixedThreadPool(4);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("需要一个runnable");
            }
        };
        for (int i = 0, size = Integer.MAX_VALUE; i < size; i++) {
            //向线程池种提交任务
            threadPool.execute(
                    //这个地方的代码等同与上面的runnable 实现类 Java8新特性
                    ()->{
                        System.out.println("需要一个runnable");
                    });
        }
    }
}

设置当前 main函数 的运行 jvm大小

image.png

第2步

image.png -Xms4m -Xmx4m

为什么会有异常:

看源代码:

public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}
  • 看看用的是什么队列:LinkedBlockingQueue
  • 在仔细看我的代码 那个for循环 可以说没有终止条件

image.png

LinkedBlockingQueue

他是无边界队列,在for无线循环的时候 他都会把任务放到 LinkedBlockingQueue 中,达到这个队列的上线 不就 提示你 内存溢出

把上面代码优化一下 让他异常表现的更明显

public class FixedThreadPoolTest {
    public static void main(String[] args) {
        //Executors.newFixedThreadPool(2);
        ExecutorService threadPool = Executors.newFixedThreadPool(4);
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                System.out.println("需要一个runnable");
            }
        };
        for (int i = 0, size = Integer.MAX_VALUE; i < size; i++) {
            //向线程池种提交任务
            threadPool.execute(
                    //这个地方的代码等同与上面的runnable 实现类 Java8新特性
                    ()->{
                        try {
                            Thread.sleep(9999999);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("需要一个runnable");
                    });
        }
    }
}

image.png

nThreads 核心线程数
0L:等待时间 0   单位是MILLISECONDS秒
LinkedBlockingQueue:无界队列
public static ExecutorService newFixedThreadPool(int nThreads) {
    return new ThreadPoolExecutor(nThreads, nThreads,
                                  0L, TimeUnit.MILLISECONDS,
                                  new LinkedBlockingQueue<Runnable>());
}

持续更新 下篇更新 newSingleThreadExecutor、、吧一块更新

  • 我知道自己写的文章比较烂,我的个人笔记,加深印象,最后我会给他合并到一起。