Collator.java

  • 该类提供了字符串比较功能
    • 可区分语言环境。可使用静态方法getInstance的时候设置语言环境
    • 具体的业务逻辑都在子类中定义
    • searching and sorting
  • 当仅进行一次比较时,该类性能较好

    • 当有一组字符串需要比较时,应该使用类CollationKey

      I/O

  • 字节流 Byte[] InputStream、OutputStream

  • 字符流 char[] Reader、Write
    • 已经把字节根据某种编码方式识别成了字符
    • FileReader
      • 默认采用Charset.defaultCharset()的值作为编码方式,且不能更改
    • InputStreamReader
      • 可以手动设置编码方式
      • new InputStreamReader(new FileInputStream(f), Charset.forName(“UTF-8”))
  • 缓存流 BufferReader、PrintWriter
    • 字节流、字符流每一次读写,都会访问硬盘 ==》性能影响
    • 所以,一次读较多数据到缓存中,减少I/O操作
    • flush操作,直接写出
  • 数据流 DataInputStream、DataOutputStream
    • 数据的格式化顺序读写
    • DataOutputStream,顺序写出字符串、数字、布尔值
    • DataInputStream,只能读取DataOutputStream写出的文件
  • 对象流 ObjectInputStream、ObjectOutStream

    • 对象序列化,这个对象类必须实现Serializable接口

      Properties.java

  • extends Hashtable

    • 代表一组键值对,字符串形式
    • 线程安全
  • 可以从字符流中加载,也可以保存到字符流中

    • 数据文件中一行表示一个键值对
    • 默认编码为 ISO 8859-1
      • 若文件为XML,编码方式为UTF-8

        SwingWorker.java

  • 抽象类,后台线程,耗时的GUI交互任务

    • 自动分配线程,并不能精确指定
    • 只会执行一次
  • 耗时任务不应该使用事件分发线程
  • Swing组件必须使用事件分发线程
  • SwingWorker的生命周期涉及三个线程
    • Current thread:调用execute方法
    • Worker thread:调用doInBackground方法
      • 所有需要后台运行的内容
      • 通过方法firePropertyChange和getPropertyChangeSupport通知PropertyChangeListeners监听器
      • 默认的属性由state和progress
    • Event Dispatch Thread
      • 所有Swing相关活动
      • 可以调用方法process和done,通知PropertyChangeListeners监听器
    • 通常,Current Thread就是Event Dispatch Thread
  • 在调用方法doInBackground之前,SwingWorker会通知PropertyChangeListeners监听器将state属性更改为StateValue.STARTED

    • 在方法doInBackground完成之后,执行了方法done,SwingWorker通知PropertyChangeListeners监听器将state属性更改为StateValue.DONE

      事件分发线程

  • 程序的main()方法会建立一个GUI并设置事件句柄

    • 当调用Frame、Dialog、Window的setVisible(true)时,就是在和GUI交互
    • 但main()可能不会只停留在用户界面上,也可能会作一些其他耗时任务
    • 如果用户在和GUI交互之前要等待时间过长的话,就可能退出
  • Event Dispatch Thread
    • 事件分发线程,java.awt.EventDispatchThread的一个实例
      • AWT库实现的监控GUI交互的线程,即循环检查系统事件队列是否有鼠标点击、键盘按下等系统事件
      • 也可以把自定义事件加入系统事件队列
    • 在绘制、更新、显示组件和受控的应用程序方面扮演着关键角色
    • 系统事件队列,FIFO,java.awt.EventQueue的一个实例
      • 每个事件都是按顺序一个个执行
      • 这是为了避免在组建重绘的过程中,组件的状态发生变化
    • 一定要小心不要在事件分发线程之外分发一个事件
    • 尽量简化事件句柄和绘制方法,否则系统的反应会变得不灵敏
    • 事件分发线程从系统事件队列取出并检测对其采取何种处理
      • eg:点击组件—》为组件调用处理句柄—》组件发送其他事件
      • 单击JButton—》事件分发线程传递一个鼠标点击事件到该Button
  • 所有的AWT组件都是线程安全的,而Swing组件不是线程安全的,必须保证任何对组件的更改都通过事件分发线程处理。如果一个线程即更新又显示一个组件,必须保证一致性

    ThreadPoolExecutor

  • 参数名 | 参数名 | 说明 | | —- | —- | | corePoolSize | 线程池维护线程的最少数量。线程池至少会保持改数量的线程存在,即使没有任务可以处理。(注意:这里说的至少是指线程达到这个数量后,即使有空闲的线程也不会释放,而不是说线程池创建好之后就会初始化这么多线程) | | maximumPoolSize | 线程池维护线程的最大数量。线程池最多可创建的线程数,即使队列中的任务满了线程数量也不会超过maximumPoolSize | | keepAliveTime | 线程池维护线程所允许的空闲时间。当线程池中的线程数量大于 corePoolSize时,超过corePoolSize的线程如果空闲时间超过keepAliveTime,线程将被终止 | | unit | 线程池维护线程所允许的空闲时间的单位,和keepAliveTime配合使用 | | workQueue | 线程池所使用的缓冲队列。ArrayBlockingQueue,LinkedBlockingQueue,SynchronousQueue,PriorityBlockingQueue | | handler | 线程池对拒绝任务的处理策略。AbortPolicy,CallerRunsPolicy,DiscardOldestPolicy,DiscardPolicy,自定义 |

  • 各类型队列说明 | 队列 | 说明 | | —- | —- | | ArrayBlockingQueue | 有界队列,FIFO,需要指定队列大小,如果队列满了,会触发线程池的RejectedExecutionHandler逻辑 | | LinkedBlockingQueue | 无界队列,FIFO,可以无限向队列中添加任务,直到内存溢出 | | SynchronousQueue | 一种阻塞队列,其中每个 put 必须等待一个 take,反之亦然。同步队列没有任何内部容量,甚至连一个队列的容量都没有。可以简单理解为是一个容量只有1的队列。Executors.newCachedThreadPool使用的是这个队列 | | PriorityBlockingQueue | 优先级队列,线程池会优先选取优先级高的任务执行,队列中的元素必须实现Comparable接口 |

  • RejectedExecutionHandler类型 | 策略名 | 说明 | | —- | —- | | AbortPolicy | 线程池默认的策略,如果元素添加到线程池失败,会抛出RejectedExecutionException异常 | | DiscardPolicy | 如果添加失败,则放弃,并且不会抛出任何异常 | | DiscardOldestPolicy | 如果添加到线程池失败,会将队列中最早添加的元素移除,再尝试添加,如果失败则按该策略不断重试 | | CallerRunsPolicy | 如果添加失败,那么主线程会自己调用执行器中的execute方法来执行改任务 | | 自定义 | 如果觉得以上几种策略都不合适,那么可以自定义符合场景的拒绝策略。需要实现RejectedExecutionHandler接口,并将自己的逻辑写在rejectedExecution方法内 |

  • Executors

    • Executors.newFixedThreadPool 创建固定线程数的线程池,使用的是LinkedBlockingQueue无界队列
    • Executors.newSingleThreadExecutor 创建只有一个线程的线程池,使用的也是LinkedBlockingQueue无界队列
    • Executors.newCachedThreadPool 改线程池使用的是SynchronousQueue,如果其创建的线程空闲时间超过60s会自动销毁

      Timer

  • 定时工具,后台线程。可以计划执行一次,也可以计划周期执行

    • 线程安全,多个线程可以共享一个Timer对象,无需外部同步
    • 所有计划任务依次执行,所以单个任务的执行时间不易过长
    • task的需要等待为(executeTime - currentTime)
    • task是否执性判断,Task.nextExecuteTime <= currentTime
  • TimerTask是一个抽象类,它的子类代表一个可以被Timer计划的任务,具体的任务在TimerTask的run方法中实现
  • 启动一个定时器的实质是启动一个线程
    • schedule与scheduleAtFixedRate启动任务的区别
    • schedule
      • 若定时器指定的起始时间是过去的某个时刻,那么当启动定时器后,会从当前时刻开始算
      • 即时间间隔从当前时间开始算起
    • scheduleAtFixedRate
      • 若果定时器指定的起始时间是过去的某个时刻,那么当启动定时器后,定时器会迅速执行完从起始时刻到当前时刻要执行的定时器任务次数,然后再每隔指定时间间隔执行一次定时器任务
      • 即时间间隔从起始时间开始算起
  • 停止计时器

    • 终止Timer线程,默认情况下,创建的Timer会一直执行
      • 调用Timer的cancel方法
      • 把Timer线程设置为Daemon守护线程,当所有的用户线程结束后,那么守护线程也会被终止
      • 当所有的任务执行结束后,删除对应Timer对象的引用
      • 调用System.exit()方法终止线程

        ToolKit

  • used to bind the various components to particular native toolkit implementations

  • 不推荐直接调用该类方法,该类更多类似于胶水作用
    • 该类的一些方法会直接调用本地操作系统