【Javaweb】多线程案例

本文详细探讨了JavaWeb中的多线程应用,包括单例模式的饿汉和懒汉模式,强调了线程安全和volatile的作用。接着介绍了生产者消费者模型,讲解了阻塞队列和其在Java标准库中的实现。然后阐述了定时器的概念,并展示了如何使用Timer类实现定时任务。最后,文章深入解析了线程池的工作原理,讨论了标准库中的线程池实现以及如何自定义线程池。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、单例模式

1,什么是单例模式

2,单例模式分类

二,生产者消费者模型

1,阻塞队列是什么

2,标准库中的阻塞队列

3,生产者消费者模型

三、定时器

1,定时器是什么

2,标准库中的定时器

3,实现定时器

四、线程池

1,线程池是什么

2,标准库中的线程池

3,实现线程池


一、单例模式

1,什么是单例模式

设计模式好比象棋中的 "棋谱". 红方当头炮, 黑方马来跳. 针对红方的一些走法, 黑方应招的时候有 一些固定的套路. 按照套路来走局势就不会吃亏

软件开发中也有很多常见的 "问题场景". 针对这些问题场景, 大佬们总结出了一些固定的套路. 按照 这个套路来实现代码, 也不会吃亏

2,单例模式分类

饿汉模式

类加载的同时, 创建实例.

//先创建一个表示单例的类
    //我们要求Singletion这个类只能有一个实例
    //饿汉模式,“饿”是指类被加载,实例就会被创建
    static class Singletion{
        //把构造方法变为私有,此时该类外部就无法new这个类的实例
        private Singletion(){}

        //创建一个static的成员,表示该类的唯一实例
        private static Singletion instance = new Singletion();

        public static Singletion getInstance() {
            return instance;
        }
    }

    public static void main(String[] args) {
        Singletion s1 = Singletion.getInstance();
        Singletion s2 = Singletion.getInstance();
        System.out.println(s1 == s2);
    }

懒汉模式

单线程

class Singleton {
    private static Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
       }
        return instance;
   }
}

但以上代码存在线程不安全的问题

对于懒汉模式,多线程调用getInstance,getInstance做了四件事

        读取instance的内容

        判断instance是否为空

        如果instance为null,就new实例

        返回实例地址

 当一个类被new两次,就不是单例模式了,如果线程更多,new的次数可能更多,不符合单例模式

多线程

static class Singletion{
        private Singletion() { }
        private static Singletion instance = null;

        public static Singletion getInstance(){
            if (instance == null){
                instance = new Singletion();
            }
            return instance;
        }

    }

保证线程安全,我们选择加锁

static class Singletion{
        private Singletion() { }
        private static Singletion instance = null;

        public static Singletion getInstance(){
            synchronized (Singletion.class){
                if (instance == null){
                    instance = new Singletion();
                }
                return instance;
            }
        }
    }

 

当多线程首次调用 getInstance, 大家可能都发现 instance 为 null, 于是又继续往下执行来竞争锁, 其中竞争成功的线程, 再完成创建实例的操作

当这个实例创建完了之后, 其他竞争到锁的线程就被里层 if 挡住了. 也就不会继续创建其他实例

 static class Singletion{
        private Singletion() { }
        private static Singletion instance = null;

        public static Singletion getInstance(){
            if (instance == null){
                synchronized (Singletion.class){
                    if (instance == null){
                        instance = new Singletion();
                    }
                }
            }
            return instance;
        }
    }
}

 涉及多个读操作,可能会被编译器优化,为了避免 "内存可见性" 导致读取的 instance 出现偏差, 于是补充上 volatile。

static class Singletion{
        private Singletion() { }
        private volatile static Singletion instance = null;

        public static Singletion getInstance(){
            if (instance == null){
                synchronized (Singletion.class){
                    if (instance == null){
                        instance = new Singletion();
                    }
                }
            }
            return instance;
        }

    }

为了保证线程安全,涉及三个要点

        1,加锁保证线程安全

        2,双重if保证效率

        3,volatile避免了内存可见性的问题

二,生产者消费者模型

1,阻塞队列是什么

阻塞队列是一种特殊的队列. 也遵守 "先进先出" 的原则. 阻塞队列能是一种线程安全的数据结构, 并且具有以下特性:

        当队列满的时候, 继续入队列就会阻塞, 直到有其他线

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-孤单又灿烂的神-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值