文章目录
1、单例模式
1.1、饿汉式
类加载到内存后,就实例化一个单例,JVM保证了线程安全。
唯一缺点:不管用到与否,类加载时就完成实例化了。
写法1
public class Singleton01 {
private static final Singleton01 INSTANCE = new Singleton01();
public static Singleton01 getInstance(){
return INSTANCE;
}
public static void main(String[] args) {
Singleton01 s1 = Singleton01.getInstance();
Singleton01 s2 = Singleton01.getInstance();
System.out.println(s1 == s2);
}
}
写法2
public class Singleton02 {
private static final Singleton02 INSTANCE;
static {
INSTANCE = new Singleton02();
}
public static Singleton02 getInstance(){
return INSTANCE;
}
public static void main(String[] args) {
Singleton02 s1 = Singleton02.getInstance();
Singleton02 s2 = Singleton02.getInstance();
System.out.println(s1 == s2);
}
}
1.2、懒汉式
实现了lazy loading,但是却带来了线程不安全。
public class Singleton03 {
private static Singleton03 INSTANCE;
private Singleton03() {
}
public static Singleton03 getInstance(){
if(INSTANCE == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Singleton03();
}
return INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++){
new Thread(
() -> System.out.println(Singleton03.getInstance())
).start();
}
}
}
运行结果:

1.3、懒汉式(线程安全)
获取实例的方法加入synchronized,虽然解决了线程安全问题,但是效率下降了。
1.3.1、synchronized修饰方法
public class Singleton04 {
private static Singleton04 INSTANCE;
private Singleton04() {
}
public static synchronized Singleton04 getInstance(){
if(INSTANCE == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Singleton04();
}
return INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++){
new Thread(
() -> System.out.println(Singleton04.getInstance())
).start();
}
}
}
1.3.2、synchronized修饰代码块
public class Singleton05 {
private static Singleton05 INSTANCE;
private Singleton05() {
}
public static Singleton05 getInstance() {
if(INSTANCE == null) {
//修饰代码块
synchronized (Singleton05.class) {
//需要双重检查,不然会线程不安全
if (INSTANCE == null) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
INSTANCE = new Singleton05();
}
}
}
return INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++){
new Thread(
() -> System.out.println(Singleton05.getInstance())
).start();
}
}
}
1.4、静态内部类方式
JVM保证单例
加载外部类时不会加载内部类,这样可以实现懒加载
public class Singleton06 {
private Singleton06() {
}
private static class Singleton06Holder {
private final static Singleton06 INSTANCE = new Singleton06();
}
public static Singleton06 getInstance(){
return Singleton06Holder.INSTANCE;
}
public static void main(String[] args) {
for (int i = 0; i < 100; i++){
new Thread(
() -> System.out.println(Singleton06.getInstance())
).start();
}
}
}
1.5、枚举方式
不仅可以解决线程同步问题,还可以防止反序列化
public enum Singleton07 {
INSTANCE;
public static void main(String[] args) {
for (int i = 0; i < 100; i++){
new Thread(
() -> System.out.println(Singleton07.INSTANCE.hashCode())
).start();
}
}
}
2、策略模式
定义一系列算法,将每一个算法封装起来,并使它们可以互相替换。策略算法让算法可以独立于使用它的客户端而变化。
Sorter需要一个比较方法,调用方可以根据不同的策略选择不同的comparator。
关系图

代码实现
Sorter.java
public class Sorter<T> {
public void sort(T[] arr, Comparator<T> comparator) {
for (int i = 0; i < arr.length - 1; i++){
int minPos = i;
for(int j = i + 1; j < arr.length; j++){
minPos = comparator.compare(arr[j], arr[minPos]) == -1 ? j : minPos;
}
swap(arr, i, minPos);
}
}
void swap(T[] arr, int i, int j){
T temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
Comparator.java
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
}
DogComparator.java
public class DogComparator implements Comparator<Dog>{
@Override
public int compare(Dog o1, Dog o2) {
if(o1.food > o2.food) return 1;
else if(o1.food < o2.food) return -1;
return 0;
}
}
CatComparator.java
public class CatComparator implements Comparator<Cat>{
@Override
public int compare(Cat o1, Cat o2) {
if(o1.weight * o1.height > o2.weight * o2.height) return 1;
else if(o1.weight * o1.height < o2.weight * o2.height) return -1;
return 0;
}
}
Dog.java
public class Dog{
int food;
public Dog(int food) {
this.food = food;
}
@Override
public String toString() {
return "Dog{" +
"food=" + food +
'}';
}
}
Cat.java
public class Cat {
int weight, height;
public Cat(int weight, int height) {
this.weight = weight;
this.height = height;
}
@Override
public String toString() {
return "Cat{" +
"weight=" + weight +
", height=" + height +
'}';
}
}
Main.java
public class Main {
public static void main(String[] args) {
Sorter<Dog> dogSorter = new Sorter<>();
Dog[] dogs = {new Dog(3), new Dog(5), new Dog(1)};
dogSorter.sort(dogs, new DogComparator());
System.out.println(Arrays.toString(dogs));
Sorter<Cat> catSorter = new Sorter<>();
Cat[] cats = {new Cat(3, 3), new Cat(2, 4), new Cat(3, 4)};
catSorter.sort(cats, new CatComparator());
System.out.println(Arrays.toString(cats));
}
}

4554

被折叠的 条评论
为什么被折叠?



