【Java学习笔记——2021.12.8】

IDEA的使用与多线程

程序、进程、线程

  • 程序:是为完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。
  • 进程:是程序的一次执行过程,或是正在运行的一个程序。是一个动态的过程:有它自身的产生、存在和消亡的过程。——生命周期
    进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域。
  • 线程:进程可进一步细化为线程,是一个程序内部的一条执行路径。
    若一个进程同一时间并行执行多个线程,就是支持多线程的。
    线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc),线程切换的开
    销小。
    一个进程中的多个线程共享相同的内存单元/内存地址空间–>它们从同一堆中分配对象,可以
    访问相同的变量和对象。这就使得线程间通信更简便、高效。但多个线程操作共享的系统资
    源可能就会带来安全的隐患。
  • 并行: 多 个 CPU 同时执行多个任务。比如:多个人同时做不同的事 。
  • 并发: 一 个 CPU( 采用时间片 同时执行多个任务。比如:秒杀、多个人做同一件事。

线程的创建和使用

  • 方式一:继承于Thread类
    1.创建一个继承于Thread类的子类;
    2.重写Thread类的run()方法;–>将此线程要执行的操作声明在run()中;
    3.创建Thread类的子类对象;
    4.通过此对象调用start()方法;–>启用当前线程,调用当前线程的run()
    若要再启动一个线程,需要重新创建一个线程对象,重新start();
  • 方式二:实现Runnable接口
    1.创建一个实现了Runnable接口的类;
    2.实现类去实现Runnable中的抽象方法:run();
    3.创建实现类的对象;
    4.将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象;
    5.通过Thread类的对象调用start();
  • 优先选择方式二,没有类的单继承性的局限性,更适合来处理多个线程有共享数据的情况;
  • 守护线程 vs 用户线程
    唯一区别:判断JVM何时离开;
    守护线程:用来服务用户线程,通过在start()方法前调用thread.setDaemon(true)可以把一个用户线程变成守护线程;

线程的生命周期

五种状态:

  • 新建: 当 一个 Thread 类或其子类的对象被声明并创建时,新生的线程对象处于新建状态;
  • 就绪: 处于 新建 状态的线程被 start() 后,将进入线程队列等待 CPU 时间片,此时它已具备了运行 的 条件 ,只是没分配到 CPU 资源;
  • 运行: 当就绪的线程被调度 并 获得 CPU 资源 时 便进入运行状态, run() 方法定义了线程的操作和功能;
  • 阻塞: 在某种特殊情况下,被人为挂起或执行输入输出操作时,让出 CPU 并临时中止自己的执行,进入阻塞状态;
  • 死亡: 线程完成了它的全部工作或线程被提前强制性 地 中止 或出现异常导致结束;

线程的同步

  • 方式一:同步代码块
    synchronized(同步监视器){
    需要被同步的代码
    }
    说明:操作共享数据的代码,即为需要被同步的代码;多个线程共同操作的变量即为共享数据;同步监视器,俗称:锁,任何一个类的对象,都可以充当锁,多个线程必须共用同一把锁。
  • 方式二:同步方法
    将要被同步的代码封装到方法中,在返回类型前 + synchronized
  • 死锁:
    不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,就形成了线程的死锁;
    出现死锁后,不会出现异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续;
  • 方式三:lock锁:
    1.实例化Reentrantlock:private Reentrantlock lock = new Reentrantlock();
    2.调用lock():lock.lock();
    3.调用解锁方法:unlock():lock.unlock();

线程的通信

  • wait():一旦执行此方法,当前线程进入阻塞状态,并释放同步监视器;
  • notify():唤醒被wait的一个线程,如果有多个 线程,就唤醒优先级高的那个线程;
  • notifyAll():唤醒所有被wait的线程;
  • 以上方法都要声明在同步代码块或同步方法中;调用者必须是同步代码块或同步方法的同步监视器,否则,会出现IllegalMonitorStateException异常;定义在java.lang.object类中;

JDK5.0新增线程创建方式

新增方式一:实现Callable接口

  • 与Runnable接口不同:
    相比run()方法,可以有返回值;
    可以抛出异常;
    支持泛型的返回值;
    需要借助FutureTask类,比如获取返回结果;
  • Future接口:
    可以对具体 Runnable 、 Callable 任务的执行结果进行取消、查询是否完成、获取结果等;
    FutrueTask 是 Futrue 接口的唯一的实现类;
    FutureTask 同时实现了 Runnable, Future 接口。它既可以作为Runnable 被线程执行,又可以 作为 Future 得到 Callable 的返回值;
  • 步骤:
    1.创建一个实现Callable实现类;
    2.实现call方法,将此线程需要执行的操作声明在call()中;
    3.创建Callable接口实现类的对象;
    4.将此Callable接口实现类的对象传递到FutureTask构造器中,创建FutureTask对象;
    5.将FutureTask的对象作为参数传递到Thread类的构造器中,创建Thread对象,并调用start();
    6.获取Callable中call方法的返回值;

新增方式二:使用线程池(实际使用比较多

  • 思路: 提前创建好多个线程,放入线程池中,使用时直接获取,使用完放回池中。可以避免 频繁创建销毁、实现重复利用。类似生活中的公共交通工具。
  • 好处:
    1.提高响应速度 (减少了创建新线程的时间
    2.降低资源消耗 (重复利用线程池中线程,不需要每次都创建
    3.便于线程管理
  • ExecutorService :真正的线程池 接口。常见子类 ThreadPoolExecutor
    1.void execute(Runnable command) :执行任务 命令,没有返回值,一般用来执行Runnable
    2.< T > Future< T > submit(Callable< T > task) task):执行任务,有返回值,一般又来执行Callable
    3.void shutdown() :关闭连接池;
  • Executors :工具类、线程池的工厂类,用于创建并返回不同类型的线程池
    1.Executors.newCachedThreadPool ()():创建一个可根据需要创建新线程的线程池;
    2.Executors.newFixedThreadPool(n ); 创建一个可重用固定线程数的线程池;
    3.Executors.newSingleThreadExecutor () :创建一个只有一个线程的线程池;
    4.Executors.newScheduledThreadPool(n )):创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
  • 步骤:
    1.提供指定线程数量的线程池
    2.执行指定线程的操作,需要提供实现Runnable接口或Callable接口实现类的对象;
    3.关闭连接池;

常用类

String

  • String 类 代表 字符串。 Java 程序中的所有字符串字面值(如 “abc” )都作为此类的实例实现。
  • String 是一个 final 类,代表 不 可变的 字符序列 。
  • 字符串 是 常量 ,用双引号引起来表示。 它们 的值在创建之后不能更改 。
  • String 对象的字符内容是存储在一个字符 数组 value[] 中。
  • 常量与常量的拼接结果在常量池 。且常量池中不会存在相同内容的常量 。
  • 只要其中有一个是变量 结果就在堆中。
  • 如果拼接的结果调用 intern() 方法 返回值就在常量池中。
  • String采用方法:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

StringBuffer

  • java . StringBuffer代表可变的字符序列,JDK1.0 中声明,可以对字符串内容进行增删,此时不会产生新的对象。
  • 很多方法与String相同。
  • 作为参数传递时,方法内部可以改变值。
  • tringBuffer类不同于String,其对象必须使用构造器生成。有三个构造器:
    1.StringBuffer():初始容量为16的字符串缓冲区;
    2.StringBuffer(int size):构造指定容量的字符串缓冲区;
    3.StringBuffer(String str):将内容初始化为指定字符串内容。
  • 常用方法:
    在这里插入图片描述
    在这里插入图片描述

java.lang.System类

  • System类提供的 public static long currentTimeMillis()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。

java.util.Date类

  • Date():使用无参构造器创建的对象可以获取本地当前时间。
  • Date(long date)
  • getTime():返回自 1970 年 1 月 1 日 00:00:00 GMT 以来,此 Date 对象表示的毫秒数。
  • toString():把此 Date 对象转换为以下形式的 String dow mon dd hh:mm:ss zzz yyyy 其中: dow 是一周中的某一天 (Sun, Mon, Tue,Wed, Thu, Fri, Sat) zzz是时间标准 。

java.text.SimpleDateFormat类

  • Date类的 API 不易于国际化,大部分被废弃了 java.text.SimpleDateFormat类是一个不与语言环境有关的方式来格式化和解析日期的具体类。
  • 它允许进行格式化:日期–>文本 、 解析:文本–>日期;
  • 格式化:
    1.SimpleDateFormat () :默认的模式和语言环境创建对象;
    2.public SimpleDateFormat (String 该构造方法可以用 参数 pattern指定的格式创建一个对象,该对象调用:
    3.public String format(Date date) 方法格式化时间对象date
  • 解析:
    public Date parse(String source) 从给定字符串的开始解析文本,以生成一个日期。

java.util.Calendar (日历)类

  • Calendar是一个抽象基类,主用用于完成日期字段之间相互操作的功能。
  • 获取Calendar实例的方法:
    1.使用Calendar.getInstance()方法;
    2.调用它的子类GregorianCalendar的构造器。
  • 一个 Calendar 的实例是系统时间的抽象表示,通过 get( int field) 方法来取得想要的时间信息。比如 YEAR 、 MONTH 、 DAY_OF_WEEK 、 HOUR_OF_DAY 、MINUTE 、 SECOND
    1.public void set( int field,int value)
    2.public void add( int field,int amount)
    3.public final Date getTime()
    4.public final void setTime (Date date)
  • 注意:
    获取月份时: 一月 是 0 ,二月是 1 ,以此类推 12 月是 11
    获取星期时: 周日是 1 ,周二是 2 。 。。。周六是 7

JDK8中新日期时间API

  • java.time:包含值对象的基础包
  • java.time.chrono:提供对不同的日历系统的访问
  • java.time.format:格式化和解析时间和日期
  • java.time.temporal:包括底层框架和扩展特性
  • java.time.zone:包含时区支持的类
  • LocalDate、LocalTime、LocalDateTime类是其中较重要的几个类,它们的实例是不可变的对象,分别表示使用 ISO 8601 日历系统的日期、时间、日期和时间。它们提供了简单 的本地日期 或时间,并不包含当前的时间 信息,也 不包含与时区相关的信息 。
    1.LocalDate 代表 IOS 格式( yyyy MM dd )的日期 可以存储 生日、纪念日等日期。
    2.LocalTime 表示一个时间,而不是 日期 。
    3.LocalDateTime 是用来表示日期和时间的, 这是一个最常用的类之一 。
    在这里插入图片描述
  • Instant:时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳 。
    在这里插入图片描述
  • java.time.format.DateTimeFormatter类:该类提供了三种格式化方法:
    在这里插入图片描述
  • 其他API:
    1.ZoneId:该类中包含了所有的时区信息一个时区的ID,如Europe/Paris
    2.ZonedDateTime:一个在 ISO 8601 日历系统时区的日期时间 如 2007 1203 T 10 15 30 01 00 Europe/Paris 。其中每个时区都对应着 ID 地区 ID 都为 区域 城市 的格式 例如:Asia/Shanghai 等
    3.Clock 使用时区提供对当前即时 、 日期和时间的访问的时钟 。
    4.持续时间:Duration用于计算两个时间间隔
    5.日期间隔:Period用于计算两个日期间隔
    6.TemporalAdjuster : 时间校正器。有时我们可能需要获取例如:将日期调整到“下一个工作日”等操作。
    7.TemporalAdjusters : 该类通过静态方法(firstDayOfXxx()/lastDayOfXxx()/ 提供了大量的常用TemporalAdjuster 的实现 。

Java比较器

自然排序:java.lang.Comparable

  • Comparable 接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序。
  • 实现 Comparable 的类必须实现 compareTo(Object obj) 方法,两个对象即通过 compareTo(Object obj) 方法的返回值来比较大小 。 如果当前对象 this 大于 形参对象 obj 则返回正整数,如果当前对象 this 小于 形参对象 obj 则返回负整数,如果当前对象 this 等于 形参对象 obj 则返回零 。
  • 实现 Comparable 接口的对象列表(和数组)可以通过 Collections.sort 或Arrays.sort 进行 自动排序。实现此接口的对象可以用作有序映射中的键或有序集合中的元素,无需指定比较器 。
  • 对于类 C 的每一个 e1 和 e2 来说,当且仅当 e1.compareTo(e2) == 0 与e1.equals(e2) 具有相同的 boolean 值时,类 C 的自然排序才叫做与 equals一致 。 建议(虽然不是必需的) 最好使自然排序与 equals 一致 。
  • Comparable的典型实现:(默认都是从小到大排列的)
    1.String :按照字符串中字符的 Unicode 值进行比较
    2.Character :按照字符的 Unicode 值来进行比较
    3.数值类型对应的包装类以及 BigInteger 、 BigDecimal :按照它们对应的数值大小进行比较
    4.Boolean true 对应的包装类实例大于false对应的包装类实例
    5.Date 、Time 等:后面的日期时间比前面的日期时间大

定制排序:java.util.Comparator

  • 当元素的类型没有实现 java.lang.Comparable 接口而又不方便修改代码,或者实现了 java.lang.Comparable 接口的排序规则不适合当前的操作,那么可以考虑使用 Comparator 的对象来 排序强行对多个对象进行整体排序的比较。
  • 重写 compare(Object o1,Object o2) 方法,比较 o1 和 o2 的大小: 如果方法返回正整数,则表示 o1 大于 o2 ;如果返回 0 ,表示相等;返回负整数,表示o1 小于 o2 。
  • 可以 将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制 。
  • 还可以使用 Comparator 来控制某些数据结构(如有序 set 或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序 。

System类

  • System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。该类位于java.lang包 。
  • 由于 该类的构造器是private的,所以无法创建该类的对象,也就是无法实例化该类。其内部的成员变量和成员方法都是 static 的,所以也可以很方便的进行调用 。
  • 成员变量:System 类内部包含 in、out 和 err 三个成员变量,分别代表标准输入流(键盘输入 ),标准输出流(显示器)和标准错误输出流(显示器)。
  • 成员方法:
    1.native long currentTimeMillis():该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时间和 GMT 时间 格林威治时间 )1970 年 1 月 1 号 0 时 0 分 0 秒所差的毫秒数。
    2.void exit(int status):该方法的作用是退出程序。其中 status 的值为 0 代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。
    3.void gc()该方法的作用是请求系统进行垃圾回收。至于系统是否立刻回收,则取决于系统中垃圾回收算法的实现以及系统执行时的情况。
    4.String getProperty(String key)该方法的作用是获得系统中属性名为 key 的属性对应的值。系统中常见
    的属性名以及属性的作用如下表所示:
    在这里插入图片描述

Math类

  • java.lang.Math提供了一系列静态方法用于 科学 计算。其 方法的参数和返回值类型一般为 double 型。
    在这里插入图片描述

BigInteger类

  • Integer 类作为 int 的包装类,能存储的最大整型值为 231-1 Long 类也是有限的,最大为 263 -1 。 如果 要表示再大的整数,不管是基本数据类型还是他们的包装类都无能为力,更不用说进行运算了。
  • java.math 包的 BigInteger 可以表示不可变的任意精度的整数 。 BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。另外, BigInteger 还提供以下运算:模算术、 GCD 计算、质数测试、素数生成、位操作以及一些其他操作。
  • 构造器:BigInteger (String val 根据字符串构建 BigInteger 对象
  • 常用方法:
    在这里插入图片描述

BigDecimal 类

  • 一般的 Float 类和 Double 类可以用来做科学计算或工程计算,但在 商业计算中,要求数字精度比较高,故用到 java.math.BigDecimal 类 。
  • BigDecimal 类支持不可变的、任意精度的有符号十进制定点数 。
  • 构造器:
    1.public BigDecimal(double val)
    2.public BigDecimal (String val)
  • 常用方法:
    1.public BigDecimal add (BigDecimal)
    2.public BigDecimal subtract (BigDecimal)
    3.public BigDecimal multiply (BigDecimal)
    4.public BigDecimal divide (BigDecimal divisor, int scale, int roundingMode)

枚举类与注解

枚举类

  • 类的对象只有有限个,确定的。称此类为枚举类;

方式一:自定义枚举类

  1. 声明Season对象的属性:private final修饰;
  2. 私有化类的构造器,并给对象属性赋值;
  3. 提供当前枚举类的多个对象public static final的修饰;

方式二:使用enum关键字定义枚举类

  1. 提供当前枚举类的对象,多个对象之间用“,”隔开,最后一个对象用“;”结束;
  2. 声明Season对象的属性:private final修饰;
  3. 私有化类的构造器,并给对象属性赋值;
  • Enum类的主要方法:
    在这里插入图片描述
  • 使用enum关键字定义的枚举类实现接口的情况
    1.实现接口,在enum类中实现抽象方法;
    2.让枚举类的对象分别实现接口中的抽象方法;

注解Annotation

  • Annotation 其实就是代码里的 特殊标记 , 这些标记可以在编译 , 类加载 , 运行时被读取 , 并执行相应 的处理。通过 使用 Annotation, 程序员可以在不改变原有逻辑的情况下 , 在源文件中嵌入一些 补充 信息 。 代码分析工具、开发工具和部署工具可以通过这些补充信息进行验证或者进行部署。
  • Annotation 可以像修饰符一样被使用 , 可用于 修饰包 类 , 构造器 , 方法 , 成员变量 , 参数 , 局部变量的声明 , 这些信息被保存在 Annotation的 “name=value” 对中 。
  • 在 JavaSE 中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等。在 JavaEE/Android 中注解占据了更重要的角色,例如用来配置应用程序的任何切面, 代替 JavaEE 旧版中所遗留的繁冗代码和 XML 配置等 。
  • 未来的开发模式都是基于注解的, JPA 是基于注解的, Spring2.5 以上都是基于注解的, Hibernate3.x 以后也是基于注解的,现在的Struts2 有一部分也是基于注解的了,注解是一种趋势 ,一定程度上可以说:== 框架 = 注解 + 反射 + 设计模式==。
  • 使用 Annotation 时要在其前面增加 @ 符号 , 并 把该 Annotation 当成一个修饰符使用。 用于修饰它支持的程序元素
  • 示例一:生成文档相关的注解
    @author标明开发该类模块的作者 多个作者之间使用 分割
    @version标明该类模块的版本
    @see参考转向 也就是相关主题
    @since从哪个版本开始增加的
    @param对方法中某参数的说明 如果没有参数就不能写
    @return对方法返回值的说明 如果方法的返回值类型是 void 就不能写
    @exception对方法可能抛出的异常进行说明 如果方法没有用 throws 显式抛出的异常就不能写
    其中:
    @param @return 和 @exception 这三个标记都是只用于方法的;
    @param的格式要求: @param 形参名 形参类型 形参说明;
    @return的格式要求: @return 返回值类型 返回值说明;
    @exception的格式要求: @exception 异常类型 异常说明;
    @param和 @exception 可以并列多个 ;
  • 示例二: 在编译时进行格式 检查 (JDK 内置的三个基本注解
    @Override: 限定重写父类方法 , 该注解只能 用于方法;
    @Deprecated : 用于表示所修饰的元素 类 , 方法等 已过 时。通常是因为所修饰的结构危险或存在更好的选择;
    @SuppressWarnings :抑制编译器警告。
  • 示例三: 跟踪 代码依赖性,实现替代配置文件功能;

自定义注解

  1. 注解声明为@interface;
  2. 内部定义成员,通常使用value表示;
  3. 可以指定成员的默认值,使用default来定义;
  4. 如果自定义注解没有成员,表明是一个标识作用;
  5. 如果注解有成员,在使用注解时,需要指明成员的值;
  6. 自定义注解必须配上注解的信息处理流程(使用反射)才有意义。

元注解

  • 用于修饰其他注解的注解;
  • @Retention只能用于修饰一个 Annotation 定义 , 用于指定该 Annotation 的生命周期 , @Rentention 包含一个 RetentionPolicy 类型的成员变量 , 使用Rentention 时必须为该 value 成员变量指定值。
  • @Target用于修饰 Annotation 定义 , 用于指定被修饰的 Annotation 能用于修饰哪些 程序元素@Target 也包含一个名为 value 的 成员变量。
  • @Documented用于指定被该元 Annotation 修饰的 Annotation 类将被javadoc 工具提取 成 文档。 默认情况 下 javadoc 是不包括注解 的 。
  • @Inherited被它修饰的 Annotation 将 具有 继承性 。如果 某个类使用了被@Inherited 修饰的 Annotation, 则其子类将自动具有 该注解。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值