线程池:


image.png

Java中的线程池是通过Executor框架实现的,该框架中用到了Executor,Executors,ExecutorService,ThreadPoolExecutor

image.png
image.png
image.png

线程池也有相应的辅助工具类 均在juc?

image.png
image.png
image.png
image.png

ThreadPoolExecutor 7参

image.png
image.png
image.png

线程池底层原理

image.png
image.png
image.png

线程池使用规范

image.png
image.png

手写线程池?

/**
 * 手写线程池
 */
public class MyThreadPoolExecutor {
    public static void main(String[] args) {
        ExecutorService threadPool = new ThreadPoolExecutor(
                2,   //核心线程数
                5,//线程池最大数
                1L,//多余corePoolSize可存活时间
                TimeUnit.SECONDS,//keepaliveTime的单位
                new LinkedBlockingQueue<>(3), //workQueue阻塞队列的数据结构,大小是3
                Executors.defaultThreadFactory(),//创建线程的方式,使用默认既可
                new ThreadPoolExecutor.AbortPolicy());//拒绝策略  默认AbortPolicy 当超过(maximumPoolSize+workQueue)时会抛出异常

        for (int i = 1; i <= 9; i++) {
            threadPool.execute(() -> {
                System.out.println(Thread.currentThread().getName() + "\t 办理业务");
            });
        }
    }
}

如何合理配置线程池?

image.png

第一种:由于I0密集型任务线程并不是一直在执行任务,则应配置尽可能多的线程,如cPU核数*2

第二种:


image.png
死锁编码及定位分析
image.png
class Resource implements Runnable {
    private String lockA;
    private String lockB;
    public Resource(String lockA, String lockB) {
        this.lockA = lockA;
        this.lockB = lockB;
    }
    @Override
    public void run() {
        synchronized (lockA) {
            System.out.println(Thread.currentThread().getName() + "\t 自己持有的:" + lockA + "\t 尝试获得:" + lockB);
            //为了效果明显 睡一会儿
            try {
                TimeUnit.SECONDS.sleep(1L);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (lockB) {
                System.out.println(Thread.currentThread().getName() + "\t 自己持有的:" + lockB + "\t 尝试获得:" + lockA);
            }
        }
    }
}

public class DeadLock {
    public static void main(String[] args) {
        String lockA = "lockA";
        String lockB = "lockB";

        new Thread(new Resource(lockA, lockB), "ThreadAAA").start();
        new Thread(new Resource(lockB, lockA), "ThreadBBB").start();
    }
}

通过 jps -l 找到进程编号
再通过jstack +进程编号 查找问题


image.png
收藏
评论加载中...