单例:
1、饿汉式:
类加载到内存后,就实例化一个单例,JVM保证线程安全,简单实用,推荐使用
唯一缺点:不管用到与否,类装载时就完成实例化
public class Singleton1 {
private static final Singleton1 INSTANCE = new Singleton1();
private Singleton1() {
}
public static Singleton1 getInstance(){
return INSTANCE;
}
public static void main(String[] args) {
Singleton1 instance1 = Singleton1.getInstance();
Singleton1 instance2 = Singleton1.getInstance();
System.out.println(instance1==instance2);
}
}
2、懒汉式
第一种:
public class Singleton2 {
private static Singleton2 INSTANCE;
private Singleton2() {
}
public static synchronized Singleton2 getInstance() {
if (INSTANCE == null) {
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
INSTANCE = new Singleton2();
}
return INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 30; i++) {
new Thread(new Runnable() {
public void run() {
System.out.println(Singleton2.getInstance().hashCode());
}
}).start();
}
}
}
懒汉式升级版:
public class Singleton2 {
private static Singleton2 INSTANCE;
private Singleton2() {
}
public static Singleton2 getInstance() {
if (INSTANCE == null) {
synchronized (Singleton2.class) {
if(INSTANCE==null) {
try {
Thread.sleep(100);
} catch (Exception e) {
e.printStackTrace();
}
INSTANCE = new Singleton2();
}
}
}
return INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 30; i++) {
new Thread(new Runnable() {
public void run() {
System.out.println(Singleton2.getInstance().hashCode());
}
}).start();
}
}
}
3、静态内部类:懒加载(内部类只会在jvm中加载一次,所以是线程安全的)
public class Singleton3 {
private Singleton3(){
}
private static class InnerSingle{
private static final Singleton3 INSTANCE = new Singleton3();
}
public static Singleton3 getInstance(){
return InnerSingle.INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 30; i++) {
new Thread(new Runnable() {
public void run() {
System.out.println(Singleton3.getInstance().hashCode());
}
}).start();
}
}
}
4、枚举单例:java创始人编写
public enum Singleton4 {
INSTANCE;
public void m(){}
public static void main(String[] args) {
for (int i = 0; i < 30; i++) {
new Thread(new Runnable() {
public void run() {
System.out.println(Singleton4.INSTANCE.hashCode());
}
}).start();
}
}
}
责任链
普通的责任链模式:
public class ChainPar {
public static void main(String[] args) {
Msg m = new Msg();
m.setMsg("大家好:<script>,,欢迎访问 mashbing.com 大家都是996.:)");
System.out.println(m);
// 处理msg
// List<Filter> list = new ArrayList<>();
// list.add(new HTMLFilter());
// list.add(new SensitiveFilter());
// for (Filter filter : list) {
// filter.doFilter(m);
// }
FilterChain fc = new FilterChain();
fc.add(new HTMLFilter())
.add(new SensitiveFilter());
FilterChain fc2 = new FilterChain();
fc2.add(new FaceFilter())
.add(new URLFilter());
fc.add(fc2);
fc.doFilter(m);
System.out.println(m);
}
}
class Msg {
private String name;
private String msg;
@Override
public String toString() {
return "Msg{" +
"name='" + name + '\'' +
", msg='" + msg + '\'' +
'}';
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
interface Filter {
boolean doFilter(Msg m);
}
class HTMLFilter implements Filter {
@Override
public boolean doFilter(Msg m) {
String r = m.getMsg();
r = r.replace('<', '[');
r = r.replace('>', ']');
m.setMsg(r);
return true;
}
}
class SensitiveFilter implements Filter {
@Override
public boolean doFilter(Msg m) {
String r = m.getMsg();
r = r.replace("996", "955");
m.setMsg(r);
return false;
}
}
class FaceFilter implements Filter {
@Override
public boolean doFilter(Msg m) {
String r = m.getMsg();
r = r.replace(":)", "^V^");
m.setMsg(r);
return true;
}
}
class URLFilter implements Filter {
@Override
public boolean doFilter(Msg m) {
String r = m.getMsg();
r = r.replace("mashibing.com", "http://mashibing.com");
m.setMsg(r);
return true;
}
}
class FilterChain implements Filter{
List<Filter> list = new ArrayList<>();
public FilterChain add(Filter filter){
list.add(filter);
return this;
}
public boolean doFilter(Msg m){
for (Filter filter : list) {
if(!filter.doFilter(m)) return false;
}
return true;
}
}
servlet责任链模式原理:
public class serverFilters {
public static void main(String[] args) {
Request request = new Request();
request.setStr("hello world");
Response response = new Response();
response.setStr("hadoop flink");
FilterChain fc = new FilterChain();
fc.add(new HTMLFilter())
.add(new SensitiveFilter())
.add(new FaceFilter())
.add(new URLFilter());
fc.doFilter(request, response);
System.out.println(request.getStr());
System.out.println(response.getStr());
}
}
class Request {
String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Request{" +
"str='" + str + '\'' +
'}';
}
}
class Response {
String str;
public String getStr() {
return str;
}
public void setStr(String str) {
this.str = str;
}
@Override
public String toString() {
return "Response{" +
"str='" + str + '\'' +
'}';
}
}
interface Filter {
boolean doFilter(Request request, Response response, FilterChain filterChain);
}
class HTMLFilter implements Filter {
@Override
public boolean doFilter(Request request, Response response, FilterChain filterChain) {
String str = request.getStr();
str += "HTMLFilter request";
request.setStr(str);
filterChain.doFilter(request, response);
String str1 = response.getStr();
str1 += "HTMLFilter response";
response.setStr(str1);
return true;
}
}
class SensitiveFilter implements Filter {
@Override
public boolean doFilter(Request request, Response response, FilterChain filterChain) {
String str = request.getStr();
str += "SensitiveFilter request";
request.setStr(str);
filterChain.doFilter(request, response);
String str1 = response.getStr();
str1 += "SensitiveFilter response";
response.setStr(str1);
return true;
}
}
class FaceFilter implements Filter {
@Override
public boolean doFilter(Request request, Response response, FilterChain filterChain) {
String str = request.getStr();
str += "FaceFilter request";
request.setStr(str);
filterChain.doFilter(request, response);
String str1 = response.getStr();
str1 += "FaceFilter response";
response.setStr(str1);
return true;
}
}
class URLFilter implements Filter {
@Override
public boolean doFilter(Request request, Response response, FilterChain filterChain) {
String str = request.getStr();
str += "URLFilter request";
request.setStr(str);
filterChain.doFilter(request, response);
String str1 = response.getStr();
str1 += "URLFilter response";
response.setStr(str1);
return true;
}
}
class FilterChain {
List<Filter> list = new ArrayList<>();
int index = 0;
public FilterChain add(Filter filter) {
list.add(filter);
return this;
}
public boolean doFilter(Request request, Response response) {
if (index == list.size()) return false;
Filter filter = list.get(index);
index++;
filter.doFilter(request, response, this);
return true;
}
}
代理模式:
静态代理:
public class TankProxy implements Moveable {
@Override
public void move() {
System.out.println("Tank moving claclacla...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new TankTimeProxy(
new TankLogProxy(
new TankProxy()
)
).move();
}
}
public interface Moveable {
void move();
}
public class TankLogProxy implements Moveable {
Moveable m;
public TankLogProxy(Moveable m) {
this.m = m;
}
@Override
public void move() {
System.out.println("moving start");
m.move();
System.out.println("moving end");
}
}
public class TankTimeProxy implements Moveable {
Moveable m;
public TankTimeProxy(Moveable m) {
this.m = m;
}
@Override
public void move() {
long start = System.currentTimeMillis();
m.move();
long end = System.currentTimeMillis();
System.out.println(end - start);
}
}
代理者和被代理者都实现了moveable接口
缺点:只能代理moveable接口类型
jdk动态代理:
public class DanimicProxy implements Movable {
@Override
public void move() {
System.out.println("Tank moving claclacla...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
DanimicProxy danimicProxy = new DanimicProxy();
Movable m = (Movable) Proxy.newProxyInstance(DanimicProxy.class.getClassLoader(),
new Class[]{Movable.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method " + method.getName() + " start..");
Object o = method.invoke(danimicProxy, args);
System.out.println("method " + method.getName() + " end!");
return o;
}
});
m.move();
}
}
interface Movable {
void move();
}
另一种写法
public class DanimicProxy implements Movable {
@Override
public void move() {
System.out.println("Tank moving claclacla...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
DanimicProxy danimicProxy = new DanimicProxy();
Movable m = (Movable) Proxy.newProxyInstance(DanimicProxy.class.getClassLoader(),
new Class[]{Movable.class},
new MyInvocationHandler(danimicProxy));
m.move();
}
}
// 此类就是代理类
class MyInvocationHandler implements InvocationHandler {
private DanimicProxy danimicProxy;
public MyInvocationHandler(DanimicProxy danimicProxy) {
this.danimicProxy = danimicProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("method " + method.getName() + " start..");
Object o = method.invoke(danimicProxy, args);
System.out.println("method " + method.getName() + " end!");
return o;
}
}
interface Movable {
void move();
}
以上两例中 m.move()方法实际上是调用了MyInvocationHandler类的invoke方法。如何实现的呢?请往下看:
将以上的main方法修改为:
也就是加了一行代码:
System.getProperties().put("jdk.proxy.ProxyGenerator.saveGeneratedFiles","true");
会生成一个字节文件,idea会自动进行反编译,可以查看其内容。
第19行的var1其实就是下面的danimicProxy。或者说是代理类。
新生成的文件继承了Proxy父类,并实现了movable接口。20行调用了super(var1)方法。就是将danimicProxy传递给父类Proxy进行初始化。33行的move方法其实就是重写的实现movable接口中的move方法。为什么会实现movable接口,因为我在main方法中指定了必须实现Movable接口。move方法的35行调用了super.h.invoke()方法,super.h是什么意思呢,这个h就是我们20行super(var1)中的var1。这个var1就是我们的代理类的一个对象,它里面有一个invoke方法。此处调用的就是这个invoke方法。这就是m.move如何调用了我们写的MyInvocationHandler类的invoke方法的原理。
此处movable接口可以有多个抽象方法。然后在MyInvocationHandler的invoke方法中根据method.getName()方法获取每个接口中每个方法的名称,然后根据这个名称,可以实现不同方法实现不同功能。如:
class MyInvocationHandler implements InvocationHandler {
private DanimicProxy danimicProxy;
public MyInvocationHandler(DanimicProxy danimicProxy) {
this.danimicProxy = danimicProxy;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object o = null;
if (method.getName().equals("move")) {
System.out.println("method " + method.getName() + " start..");
o = method.invoke(danimicProxy, args);
System.out.println("method " + method.getName() + " end!");
} else if (method.getName().equals("stop")) {
System.out.println("method " + method.getName() + " start..");
o = method.invoke(danimicProxy, args);
System.out.println("method " + method.getName() + " end!");
}
return o;
}
}
interface Movable {
void move();
void stop();
}
我们还没说MyInvocationHandler类中的invoke方法的参数:先说第二个参数:这个就是接口中的抽象方法,第三个参数:这个就是第二个参数的方法需要的参数。第一个参数:此处需要看看是谁调用了invoke方法,找到调用invoke方法的人,可以找到其传给invoke方法的参数。可以看到是super.h.invoke()调用了invoke方法。传进去的第一个参数是this.其实就是下图中的m。
上面我们讲了中间自动生成了一个类,即$Proxy类。那到底是怎么生成的呢?
此处比较复杂,不想洗阐述,但可以简单说一说:
其中间会调用到jdk.internal.org.objectweb.asm类中的内容,即asm,asm可以直接修改类编译后的字节文件,正式因为java的sam可以直接修改类编译后的字节文件,所以java也被称为动态语言。那什么叫动态语言,即程序运行过程中可以直接修改类编译后的的字节码。动态语言不是靠反射体现的,反射是可以获取,但不可以修改。
以上就是jdk的动态代理,要有其他类型的动态代理
cglib动态代理
jdk的反射动态代理需要实现一个接口;而cglib却不需要。
public class CglibProxy {
public static void main(String[] args) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(Cat.class);
enhancer.setCallback(new TimeMethodInterceptor());
Cat cat = (Cat) enhancer.create();
cat.move();
}
}
class TimeMethodInterceptor implements MethodInterceptor{
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// System.out.println(obj.getClass().getSuperclass().getName());
System.out.println("before");
Object result = null;
result = proxy.invokeSuper(obj,args);
System.out.println("after");
return result;
}
}
class Cat{
public void move(){
System.out.println("Tank moving claclacla...");
try {
Thread.sleep(12);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
此方法如何获取被代理的类呢?就是上面注释的代码
Builder
public class Terrain {
Wall w;
Fort f;
Mine m;
}
class Wall {
int x, y, w, h;
public Wall(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
}
class Fort {
int x, y, w, h;
public Fort(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
}
class Mine {
int x, y, w, h;
public Mine(int x, int y, int w, int h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
}
public interface TerrainBuilder {
TerrainBuilder builderWall();
TerrainBuilder builderFort();
TerrainBuilder builderMine();
Terrain build();
}
public class ComplexTerrainBuilder implements TerrainBuilder {
Terrain terrain = new Terrain();
@Override
public TerrainBuilder builderWall() {
terrain.w = new Wall(1, 2, 3, 4);
return this;
}
@Override
public TerrainBuilder builderFort() {
terrain.f = new Fort(1, 2, 3, 4);
return this;
}
@Override
public TerrainBuilder builderMine() {
terrain.m = new Mine(1, 2, 3, 4);
return this;
}
@Override
public Terrain build() {
return terrain;
}
}
public class Main {
public static void main(String[] args) {
ComplexTerrainBuilder builder = new ComplexTerrainBuilder();
Terrain t = builder.builderFort().builderMine().builderWall().build();
}
}
Builder案例:
public class Person {
int id;
String name;
int age;
double weight;
int score;
Location loc;
public Person() {
}
public static class PersonBuilder {
Person p = new Person();
public PersonBuilder basicInfo(int id, String name, int age) {
p.id = id;
p.name = name;
p.age = age;
return this;
}
public PersonBuilder weight(double weight) {
p.weight = weight;
return this;
}
public PersonBuilder score(int score) {
p.score = score;
return this;
}
public PersonBuilder loc(String street, String roomNo) {
p.loc = new Location(street, roomNo);
return this;
}
public Person build() {
return p;
}
}
}
class Location {
String street;
String roomNo;
public Location() {
}
public Location(String street, String roomNo) {
this.street = street;
this.roomNo = roomNo;
}
}
public class PersonMain {
public static void main(String[] args) {
Person p = new Person.PersonBuilder()
.basicInfo(1,"zhangsan",15)
.score(20)
.weight(200)
.build();
}
}
观察者
public class TankFireEvent {
Tank tank;
public Tank getSource() {
return tank;
}
public TankFireEvent(Tank tank) {
this.tank = tank;
}
}
public class TankFireHandler implements TankFireObserver {
@Override
public void actionOnFire(TankFireEvent e) {
Tank t = e.getSource();
t.fire();
}
}
public interface TankFireObserver {
void actionOnFire(TankFireEvent event);
}
Adapter(Wrapper)
public class Main {
public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("path");
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String line = br.readLine();
while (line != null && !line.equals("")) {
System.out.println(line);
}
br.close();
}
}
桥接模式
public abstract class Gift {
GiftImp giftImp;
}
public abstract class GiftImp {
}
public class WarmGift extends Gift{
public WarmGift(GiftImp giftImp){
this.giftImp = giftImp;
}
}
public class WildGift extends Gift {
public WildGift(GiftImp giftImp) {
this.giftImp = giftImp;
}
}
public class Book extends Gift {
}
public class Floor extends GiftImp {
}
public class GG {
public void chase(MM mm){
WarmGift g = new WarmGift(new Floor());
}
}
此处的MM没有具体实现,此处仅仅表明桥接模式的用法即可。