Article Directory
1. Template: there are abstract methods in the class must be abstract
Decorator (IO stream), iterator (collection)
package com.atguigu.test02.abstract_;
// 编写一个类,包含一个方法,可以统计 你执行任意代码的运行时间
public class TestTemplate {
public static void main(String[] args) {
MyCalTime my = new MyCalTime();
long time = my.getTime();
System.out.println("耗时:" + time + "毫秒");
}
}
abstract class CalTime{
//模板类
//可以计算任意一段代码的运行时间 //这里加final的目的是不希望子类重写,改写我的算法的结构
public final long getTime(){
long start = System.currentTimeMillis(); //(1)获取开始时系统时间
doWork(); //(2)执行xxxx
long end = System.currentTimeMillis(); //(3)获取结束时系统时间
return end - start; //(4)计算时间差
}
protected abstract void doWork(); //protected的目的,希望只是子类中进行访问和重写
}
class MyCalTime extends CalTime{
@Override
protected void doWork() {
//重写抽象方法
long sum = 0;
for(int i=1; i<=100000; i++){
sum += i;
}
System.out.println("sum = " + sum);
}
}
2. Singleton: multi-threaded
package com.atguigu.test17;
import org.junit.Test;
/*
* 单例:某个类只能有唯一的一个实例对象。如何实现单例?
* 1、饿/恶汉式: 不管我们使用者是否需要这个对象,它都上来先给你创建好这个唯一的对象。
* (1)枚举类型
*
* (2)形式二:class SingleClass
* ①构造器私有化
* ②用一个全局的静态的常量,来保存这个唯一的实例对象
*
* (3)形式三:class Single
* ①构造器私有化
* ②用一个私有的静态的常量,来保存这个唯一的实例对象
* ③提供一个静态方法,来返回这个常量对象
*
*
* 2、懒汉式: 延迟创建对象。当使用者来或者这个对象,要用到对象时,我再创建。
* (1)形式一:见下面,考虑线程安全问题和性能问题
* (2)形式二:内部类形式
*/
public class Test17 {
@Test
public void test1(){
SingleEnum s1 = SingleEnum.INSTANCE;
SingleEnum s2 = SingleEnum.INSTANCE;
System.out.println(s1 == s2); //true
}
@Test
public void test2(){
// SingleEnum.test();//此时我并没有需要用到这个INSTANCE对象,但是它也创建出来SingleEnum对象,单例恶汉式
}
@Test
public void test3(){
SingleClass s1 = SingleClass.INSTANCE;
SingleClass s2 = SingleClass.INSTANCE;
System.out.println(s1==s2); //true,地址一样,只有一个对象。
}
@Test
public void test4(){
Single s1 = Single.getInstance();
Single s2 = Single.getInstance();
System.out.println(s1 == s2); //true
}
@Test
public void test5(){
LazyClass s1 = LazyClass.getInstance(); //getInstance()里必有new
LazyClass s2 = LazyClass.getInstance();
System.out.println(s2 == s1);
}
LazyClass s1;
LazyClass s2;
@Test
public void test6(){
//匿名的内部类,继承Thread类。=后面是子类,然后多态
Thread t1 = new Thread(){
public void run(){
s1 = LazyClass.getInstance();
}
};
Thread t2 = new Thread(){
public void run(){
s2 = LazyClass.getInstance();
}
};
t1.start();
t2.start();
try {
//这里用join的目的是,为了两个子线程都执行完,再执行主线程的System.out.println(s1);
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(s1);
System.out.println(s2);
System.out.println(s1 == s2);
}
}
//111111111111111111111111111111111111111111111111111111111111111111111111111111111饿汉式
enum SingleEnum{
INSTANCE; //单例,枚举只有一个 //对应test1()
// public static void test(){ //用这个方法不用上面这个INSTANCE对象 //对应test2()
//..
// }
}
//形式二 //对应test3()
class SingleClass{
//1.5之前老版的枚举
public static final SingleClass INSTANCE = new SingleClass();
private SingleClass(){
}
}
//形式三 //对应test4()
class Single{
private static final Single INSTANCE = new Single();
private Single(){
}
public static Single getInstance(){
return INSTANCE;
}
}
//11111111111111111111111111111111111111111111111111111111111111111111111111111111懒汉式
//形式一
class LazyClass{
//对应test6()
private static LazyClass instance; //不加final,可以不用new出来 //加final必须new SingleClass()
private LazyClass(){
}
public static LazyClass getInstance(){
if(instance == null){
//提高效率,已创建对象就没必要再进去,直接最后return instance; 未创建对象进入
synchronized(LazyClass.class){
//当前类的Class对象,静态方法不能出现this
if(instance == null){
//安全判断
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new LazyClass();
}
}
}
return instance;
}
//安全没问题,但是认为不是最优的,性能差。
//instance对象创建好了,第一次和第二次有竞争关系,后面没必要再等锁,对象已经new好了,直接拿就行
/* public synchronized static LazyClass getInstance(){
if(instance == null){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new LazyClass();
}
return instance;
}*/
//有线程安全问题 如下图所示
/* public static LazyClass getInstance(){
// return new LazyClass();//错误的,每次都new新的对象
if(instance == null){ //下次有的时候就不进来了
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
instance = new LazyClass();
}
return instance;
}*/
}
//形式二
class Lazy{
private Lazy(){
}
private static class Inner{
public static final Lazy INSTANCE = new Lazy();//在内部类中,创建外部类的唯一对象
}
public static Lazy getInstance(){
return Inner.INSTANCE; //用到getInstance方法才会new Lazy(),也是懒汉式
}
}
The following figure corresponds to test5(), and it prints false because it is new every time.
Add Thread.sleep(100) to the white line in the following figure.
Station B/Zhihu/WeChat Official Account: Code Farming Programming Record