当前位置:   article > 正文

多线程新手村3--多线程代码案例

多线程新手村3--多线程代码案例

1.1 单例模式

单例模式是设计模式中非常经典的一种。那么有同学肯定就会好奇了,什么是设计模式呢?

设计模式简单的说就是程序员的“棋谱”,我们下象棋时肯定或多或少都背过棋谱,例如当头炮、马后炮等,设计模式也是这样,开发过程中常常会遇到一些经典场景,用固定的解决方案去解决这些问题,这就是设计模式,今天我们先来介绍一下单例模式。

单例模式是指某个类只能实例化一个对象,不能有多个,这一点在很多场景中都会用到,例如数据库中的DateSource实例就只需要一个;单例模式又有两种实现方式,分别为饿汉模式和懒汉模式。

1.1.1 饿汉模式

在类加载的时候,创建实例(比较急切)

可以看到,由于将构造方法设为私有,所以当我们想要自己实例化一个对象的时候,编译器会报错,此时,这个类将只会有加载类时实例化的那一个对象,无法再实例化出其它对象。

1.1.2 懒汉模式

只有当需要的时候才创建实例

上述代码可以看出,只有当首次调用getInstance方法时才会创建实例,否则将不会创建实例。

单线程中懒汉模式没有问题,但是放在多线程中,就会存在许多bug!

1.1.3 懒汉模式(多线程版)

首先要解决一个疑惑,为什么饿汉模式的单线程都不会有bug,但是懒汉模式的多线程会存在bug呢?是因为饿汉模式的getInstance方法只有读功能,但是懒汉模式的getInstance方法却既可读又可写,两个线程对于同一个变量进行写操作,就很容易出现问题。所以我们要加锁,将操作变为原子性的,这样就不会出现问题了。

1、这里的加锁是为了保证原子性操作,防止代码出bug(new多个对象出来)

2、这里再一次判断对象是否为空是为了确定要不要加锁,因为如果不加这个代码的话,每次调用这个方法都会加锁,但是加锁很费时,效率很低,不好!

3、此处的volatile关键字是为了防止出现指令重排序问题。

1.2 阻塞队列

阻塞队列是多线程代码中常用的一种数据结构。

所谓阻塞队列,其实就是加了阻塞功能的队列。

a)如果队列为空,继续出队列,就会发生阻塞,直到其它线程向队列中加入元素。

b)如果队列为满,继续入队列,也会发生阻塞,直到其它线程向队列中取走元素。

阻塞队列,最大的意义是用来实现“生产者消费者模型”

“生产者消费者”模型的意义:

1、解耦合(单独设置一个队列,使原本两个直接进行数据交互的元素通过这个队列进行交互)

2、削峰填谷

当数据请求量很大的时候,如果没有阻塞队列的话,服务器A一直给服务器B发数据,就可能使服务器B崩溃;但是如果设置一个阻塞队列,那么A只需要将数据放入队列中,如果B此时已达到最大处理负荷的话,那B只需要慢慢的取出队列中的数据处理即可;反之,如果此时数据请求量很小,那么服务器B就可以慢慢地消耗掉堆积在阻塞队列中的数据。

1.3 阻塞队列的代码实现

以上代码就是自己实现了一个简易的阻塞队列,可以用作一个简单的“生产者消费者”模型。注意两个wait和notify都是互相唤醒的,无法自己唤醒自己。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/678406
推荐阅读
相关标签
  

闽ICP备14008679号