- 🎥 个人主页:Dikz12
- 📕格言:那些在暗处执拗生长的花,终有一日会馥郁传香
- 欢迎大家👍点赞✍评论⭐收藏
目录
单例模式
饿汉模式
懒汉模式
阻塞队列
生产者-消费者模型意义
定时器
单例模式
单例模式就是,约定某个类,只能有一个实例,通过编码技巧,让编译器强制检查.(在类里以前创建好实例,用private修饰构造方法). 效果就跟 final , @Override一样.
饿汉模式
饿汉模式代码实现,就只需要读取数据,多线程读,是线程安全的操作. (代码如下: )
class Singleton {//现在类的内部获得实例private static Singleton instance = new Singleton();// 后续如果想使用这个类的实例, 都通过 getInstance 方法来获取.public static Singleton getInstance() {return instance;}// 设置程私有的构造方法private Singleton() {}
}
懒汉模式
相对于饿汉模式,就更加灵活,非必要不创建,减少了一些工作量,提高效率.但是,有收益的同时,肯定还会有风险 ,懒汉模式,既有读,也有写,就会涉及到线程不安全问题.
1.加锁. 这锁要加到什么位置合适.(涉及到修改操作只是在第一次实例化的时候会进行修改,后面都是读操作).
2.双重if,减少加锁次数.
3.解决指定重排序问题.
new 操作会涉及到指令重排序. new操作可以分为三步:
1) 申请内存空间
2)在内存空间构造对象
3) 把内存地址,赋值给引用
上诉三步,1)一定是先执行的, 哪种顺序对于单线程是没有影响的.
而对于多线程就会出问题,当线程t1 按照 1) 3) 2)顺序执行,就可能会出现2)还没执行完的时候也,另一个线程t2,已经开始执行,instance == null 就会不成立,t2线程就拿到另一个非法对象.
class SingletonLazy {// 3.解决指定重排序 问题private static volatile SingletonLazy instance = null;public static SingletonLazy getInstance() {// 2.双重ifif (instance == null) {//1.synchronized (SingletonLazy.class) {if (instance == null) {instance = new SingletonLazy();}}}return instance;}private SingletonLazy() {}
}
阻塞队列
是多线程代码中比较常用的一种数据结构. 也是一种特殊的队列.
1.线程安全
2.带有阻塞特性
a)如果队列为空,继续出队列,就会阻塞等待,阻塞到其它线程往对列里添加元素
b)如果队列为满,继续入队列,也会发生阻塞等待,阻塞到其它线程从队列中取走元素为止.
阻塞队列的最大意义,就是可以用来实现"生产者-消费者模型".
生产者-消费者模型意义
1.解耦合
2.削峰填谷
class MyBlockingQueue {//队列大小private String[] date = new String[500];//队列头private volatile int head = 0;//队列下一个元素的位置private volatile int rear = 0 ;//队列个数private volatile int usedSized = 0;//入队public void put(String elem) throws InterruptedException {synchronized (this) {/* if (usedSized == date.length) {//队列满了return;}*/while (usedSized == date.length) {//队列满了// return;// 如果是队列满, 继续插入元素, 就会阻塞this.wait();}date[rear] = elem;rear = (rear + 1) % date.length;usedSized++;this.notify();}}//出队public String take() throws InterruptedException {synchronized (this) {while (usedSized == 0) {//队列为空// return null;this.wait();}String ret = date[head];head = (head + 1) % date.length;usedSized--;this.notify();return ret;}}
}
public class Demo22 {public static void main(String[] args) {MyBlockingQueue queue = new MyBlockingQueue();//消费者Thread t1 = new Thread(() -> {while (true) {try {String ret = queue.take();System.out.println("消费元素:"+ret);Thread.sleep(500);} catch (InterruptedException e) {e.printStackTrace();}}});//生产者Thread t2 = new Thread(() -> {int num = 1;while (true) {try {queue.put(num+"");System.out.println("生产元素"+num);num++;Thread.sleep(30);} catch (InterruptedException e) {e.printStackTrace();}}});t1.start();t2.start();}
}
运行效果:
定时器
约定一个时间,时间到达之后,开始执行某个代码的逻辑. 定时器是非常常见的,尤其是在网络通信的时候.
在标准库里,也是有现成的定时器实现.
public static void main(String[] args) {Timer timer = new Timer();timer.schedule(new TimerTask() {@Overridepublic void run() {System.out.println("执行定时器任务!");}},5000);System.out.println("程序启动!");}
运行效果: