Singleton 单例模式
单例模式能保证某个类在程序中只存在唯⼀⼀份实例,⽽不会创建出多个实例。
单例模式最常⻅的实现⽅的是"饿汉"和"懒汉"两种
饿汉模式,运行即创建
java
class Singleton{
private static Singleton instance=new Singleton();
private static Singleton getinstance(){
return instance;
}
//构造方法私有化,仅限在Singleton类中实例化,确保单例化
private Singleton(){
}
}
懒汉模式,需要时再创建
java
class Singleton{
private static Object locker=new Object();
//volatile修饰instance
private static volatile Singleton instance=null;
public static Singleton getinstance(){
if (instance==null){
synchronized (locker){
if (instance==null){
instance=new Singleton();
}
}
}
//实例化时原子操作
return instance;
}
//构造方法私有化,仅限在Singleton类中实例化,确保单例化
private Singleton(){
}
}
饿汉模式不存在线程安全问题,懒汉模式当多个线程调用getInstance⽅法,就可能导致创建 出多个实例,后面的实例会覆盖前面实例,资源浪费。

⼀旦实例已经创建好了,后⾯再多线程环境调⽤getInstance就不再有线程安全问题了(不再修改 instance 了)
使用锁保证原子性
java
//判断是否需要加锁,已经创建实例后减少资源浪费
if (instance==null){
synchronized (locker){
//判断是否需要实例化
if (instance==null){
instance=new Singleton();
}
}
}
但线程在加锁操作时仍会被调度,导致t1线程中instance使用了未初始化的实例,因此需要加入volatile避免重排序

java
class DBUtil {
private static volatile DataSource dataSource = null;
public static DataSource getInstance() {
if (dataSource == null) {
synchronized (DBUtil.class) {
if (dataSource == null) {
MysqlDataSource ds = new MysqlDataSource();
ds.setUrl("jdbc:mysql://127.0.0.1:3306/java117?characterEncoding=utf8&useSSL=false");
ds.setUser("root");
ds.setPassword("2222");
dataSource = ds;
}
}
}
return dataSource;
}
private DBUtil{}
}
阻塞队列
阻塞队列是⼀种特殊的队列.也遵守"先进先出"的原则,具有线程安全的阻塞队列
1.当队列满的时候,继续⼊队列就会阻塞,直到有其他线程从队列中取⾛元素.
2.当队列空的时候,继续出队列也会阻塞,直到有其他线程往队列中插⼊元素.
阻塞的队列的应用场景:生产消费者模型
阻塞队列的使用
在Java标准库中内置了阻塞队列.如果我们需要在⼀些程序中使⽤阻塞队列,直接使⽤标准库中的即 可.
1.BlockingQueue是⼀个接⼝.真正实现类包括LinkedBlockingQueue/ArrayBlockingQueue/PriorityBlockingQueue.
2.put⽅法 ⽤于阻塞式的⼊队列,take⽤于阻塞式的出队列.
3.BlockingQueue也有offer,poll,peek等⽅法,但是这些⽅法不带有阻塞特性