Java笔记3--线程池&死锁

线程池:


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
全部评论

相关推荐

Natrium_:这时间我以为飞机票
点赞 评论 收藏
分享
一个菜鸡罢了:哥们,感觉你的简历还是有点问题的,我提几点建议,看看能不能提供一点帮助 1. ”新余学院“别加粗,课程不清楚是否有必要写,感觉版面不如拿来写一下做过的事情,教育经历是你的弱势就尽量少写 2. “干部及社团经历”和“自我评价”删掉 3. 论文后面的“录用”和“小修”啥的都删掉,默认全录用,问了再说,反正小修毕业前肯定能发出来 4. 工作经验和研究成果没有体现你的个人贡献,着重包装一下个人贡献
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务