单例
饿汉:线程安全,类初始化的时候就会触发类的实例化,所以保证只有一个,
缺点:但是会浪费内存,如果不使用单例,就会一直存在
public class Singleton {
//在静态初始化器中创建单例实例,这段代码保证了线程安全
private static final Singleton instance = new Singleton();
//Singleton类只有一个构造方法并且是被private修饰的,所以用户无法通过new方法创建该对象实例
private Singleton(){}
public static Singleton getInstance(){
return instance;
}
}
懒汉:synchronized加锁线程安全
public class Singleton {
private static Singleton instance;
private Singleton (){}
//没有加入synchronized关键字的版本是线程不安全的
public static synchronized Singleton getInstance() {
//判断当前单例是否已经存在,若存在则返回,不存在则再建立单例
if (instance == null) {
instance = new Singleton();
}
return instance;
}
双重校验锁:双重加锁(线程安全)
public class Singleton {
private static volatile Singleton instance;
private Singleton() { }
public static Singleton getInstance() {
if (instance == null) {
synchronized (Singleton.class){
if(instance == null){
instance = new Singleton();
}
}
}
return instance;
}
}
- 双重判断的原因?
- 第一个判断减少锁的使用,提升性能
- 多个线程同时等待锁,当第一个创建后,就不需要其他线程重复重建
- volatile的理解
- 禁止重排序导致instance获取失败(3)。
- new Singleton()方法执行时可能导致分配了空间,并指向了内存空间,但是没有赋值,这样另一个线程拿到后会导致出错
静态内部类:(线程安全)
public class Singleton {
//私有构造方法
private Singleton (){
}
private static class SingletonHelper{
//声明成员变量
private static final Singleton instance = new Singleton();
}
//对外提供接口获取该实例
public static Singleton getSingleton(){
return SingletonHelper.instance;
}
}
枚举单例:(线程安全)
public enum Singleton {
INSTANCE;
public void doSomething() {
System.out.println("doSomething");
}
}
调用方法:
public class Main {
public static void main(String[] args) {
Singleton.INSTANCE.doSomething();
}
}
直接通过Singleton.INSTANCE.doSomething()的方式调用即可。方便、简洁又安全。
生产者消费者
生产者添加数据,消费者自己从中间件中获取信息,通过中间件管理数据
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author kangsx
* @description
* @date 2020/5/13
*/
public class Mode1 {
static class Box{
private Queue<Integer> list = new LinkedList<>();
int maxSize = 50;
private void put(int i){
synchronized (this){
while(list.size()>=maxSize){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
list.add(i);
notifyAll();
}
}
private int get(){
int i = 0;
synchronized (this){
while (list.size()<=0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i = list.remove();
notifyAll();
}
return i;
}
}
static class Producer extends Thread{
private Box box;
public Producer(Box box) {
this.box = box;
}
@Override
public void run() {
super.run();
box.put(5);
}
}
static class Consumer extends Thread{
private Box box;
public Consumer(Box box) {
this.box = box;
}
@Override
public void run() {
super.run();
int i = box.get();
System.out.println("i = " + i);
}
}
public static void main(String args[]){
Box box = new Box();
//5个生产者
for(int i = 0;i<5;i++) {
new Producer(box).start();
}
//5个消费者
for(int i = 0;i<5;i++){
new Consumer(box).start();
}
}
}
观察者
发布者发送数据到订阅者
import java.util.ArrayList;
/**
* @author kangsx
* @description
* @date 2020/5/13
*/
public class Mode2 {
static public interface IObserver {
void update(int temp);
}
static public interface IObservable {
void register(IObserver iObserver);
void unregister(IObserver iObserver);
void notifyObserver();
}
//被观察者(发布者)
static class Observable implements IObservable {
private ArrayList<IObserver> list = new ArrayList<>();
private int temp;
@Override
public void register(IObserver iObserver) {
list.add(iObserver);
}
@Override
public void unregister(IObserver iObserver) {
list.remove(iObserver);
}
@Override
public void notifyObserver() {
for (int i = 0; i < list.size(); i++) {
list.get(i).update(temp);
}
}
public void setTemp(int temp) {
this.temp = temp;
}
}
//观察者1(订阅者)
static class Observer1 implements IObserver {
@Override
public void update(int temp) {
System.out.println("Observable1更新为 = " + temp);
}
}
//观察者2(订阅者)
static class Observer2 implements IObserver {
@Override
public void update(int temp) {
System.out.println("Observable2更新为 = " + temp);
}
}
public static void main(String args[]){
Observable observable = new Observable();
Observer1 observer1 = new Observer1();
Observer2 observer2 = new Observer2();
observable.register(observer1);
observable.register(observer2);
observable.setTemp(32131232);
observable.notifyObserver();
}
}
建造者模式
提供复杂参数的对象构造,完全由调用方选择参数配置,反之使用默认。
public class Computer {
//显示器
String display;
//cpu型号
String cpu;
//主板型号
String mainBoard;
//显卡型号
String gpu;
public Computer(Builder builder) {
this.display = builder.display;
this.cpu = builder.cpu;
this.mainBoard = builder.mainBoard;
this.gpu = builder.gpu;
}
@Override
public String toString() {
return "显示器是" + display + "\ncpu是" + cpu + "\n主板是" + mainBoard + "\n显卡是" + gpu;
}
static class Builder{
//显示器
String display;
//cpu型号
String cpu;
//主板型号
String mainBoard;
//显卡型号
String gpu;
public Builder(){
this.display = "三星曲屏";
this.cpu = "i5 8400";
this.mainBoard = "华硕Z360-B";
this.gpu = "GTX 1050Ti";
}
public Builder setDisplay(String display) {
this.display = display;
return this;
}
public Builder setcpu(String cpu) {
this.cpu = cpu;
return this;
}
public Builder setMainBoard(String mainBoard) {
this.mainBoard = mainBoard;
return this;
}
public Builder setGpu(String gpu) {
this.gpu = gpu;
return this;
}
public Computer build(){
return new Computer(this);
}
}
public static void main(String args[]){
Computer computer = new Computer.Builder()
.setcpu("i9 4700u")
.setGpu("GTX 2060Ti")
.setMainBoard("华硕Z480")
.build();
System.out.println(computer.toString());
}
}
工厂模式
代理模式
对原有功能进行封装,访问对象不能直接访问原有功能,只能访问我们的功能传达,我们就是代理,作为原有功能和访问对象之间的中介
静态代理:
package proxy;
public class ProxyTest {
public static void main(String[] args) {
Proxy proxy = new Proxy();
proxy.Request();
}
}
//抽象主题
interface Subject {
void Request();
}
//真实主题
class RealSubject implements Subject {
public void Request() {
System.out.println("访问真实主题方法...");
}
}
//代理
class Proxy implements Subject {
private RealSubject realSubject;
public void Request() {
if (realSubject == null) {
realSubject = new RealSubject();
}
preRequest();
realSubject.Request();
postRequest();
}
public void preRequest() {
System.out.println("访问真实主题之前的预处理。");
}
public void postRequest() {
System.out.println("访问真实主题之后的后续处理。");
}
}
动态代理:
IRetrofit iRetrofit = (IRetrofit) Proxy.newProxyInstance(IRetrofit.class.getClassLoader(), new Class<?>[]{IRetrofit.class}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("-----调用前执行");
if(method.getDeclaringClass() == Object.class) {
System.out.println("-----调用前执行Object");
return method.invoke(IRetrofit.class, args);
}
IRetrofit iRetrofit1 = new IRetrofit() {
@Override
public void test() {
System.out.println("------test1");
}
@Override
public void kang() {
System.out.println("------kang1");
}
};
Object object = method.invoke(iRetrofit1,args);
System.out.println("-------调用后执行");
return null;
}
});
iRetrofit.kang();
打印如下:
-----调用前执行
------kang1
-------调用后执行
即想调用那个方法都可以,在invoke中做了代理,利用反射执行该类