Java容器和多线程

实习记录_3实习记录_3Java容器Java容器分类List集合ArrayListLinkedListVectorSet集合TreeSetHashSetLinkedHashSetQueue集合LinkedListPriorityQueueMap集合HashtableHashMapLinkedHashMapTreeMapJava多线程编程Java线程属性线程状态线程优先级Java Thread类重要方法Thread对象调用方法Thread静态方法线程创建通过实现Runnable接口通过继承Thread类创建线
摘要由CSDN通过智能技术生成

Java容器

Java容器分类

  • Java容器主要分成两大类:Collection和Map,区别就是Collection是一个槽的,Map是两个槽的(键值对)

  • Collection划分为:List,Set,Queue

    • List接口常见有:ArrayList,LinkedList,AbstractList, CopyOnWriteArrayList, Vector(已过时),Stack
    • Set接口常见有:HashSet,TreeSet,LinkedHashSet,AbstractSet,CopyOnWriteArraySet,EnumSet
    • Queue接口常见有:(阻塞队列)ArrayBlockQueue、PriorityBlockingQueue、LinkedBlockingQueue(双端队列)ArrayDeque、LinkedBlockingDeque、LinkedList
  • Map一般使用:Hashmap、Treemap、Hashtable、AbstractMap、ConcurrentHashMap、 LinkedHashMap、WeakHashMap

  • 容器类图
    在这里插入图片描述

List集合

ArrayList

  • ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素(类似于STL vector)
  • ArrayList 是一个数组队列,提供了相关的添加、删除、修改、遍历等功能
  • 基于动态数组实现
  • 适合于顺序添加、随机访问 (RandomAccess 接口标识该类支持快速随机访问) 的场景
  • 允许插入为空,允许插入重复数据
  • 线程不安全

数组的默认大小为 10;添加元素时候,如果容量不足,需要使用 grow() 方法进行扩容,新容量是旧容量的 1.5
倍,扩容操作还需要将旧数组中的元素 copy 到新数组中,该过程比较耗费性能。 添加一个元素,同样需要 copy
一次,因此该过程是比较耗费性能的。
删除中间某个元素时候,后面元素需要整体向前移动,因此该过程也是耗费性能,而对于删除最后一个元素,则可以直接设为 null,让 gc
垃圾回收机制去回收。

  • 常用方法列表
    在这里插入图片描述
    在这里插入图片描述

LinkedList

  • Java LinkedList(链表) 类似于 ArrayList,是一种常用的数据容器

  • 与 ArrayList 相比,LinkedList 的增加和删除对操作效率更高,而查找和修改的操作效率较低

  • 以下情况使用 ArrayList :

    • 频繁访问列表中的某一个元素
    • 只需要在列表末尾进行添加和删除元素操作
  • 以下情况使用 LinkedList :

    • 你需要通过循环迭代来访问列表中的某些元素
    • 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作
  • 基于双向链表实现

  • 允许插入为空,允许插入重复数据

  • 线程不安全

  • LinkedList类图
    在这里插入图片描述

    • LinkedList 继承了 AbstractSequentialList 类
    • LinkedList 实现了 Queue 接口,可作为队列使用
    • LinkedList 实现了 List 接口,可进行列表的相关操作
    • LinkedList 实现了 Deque 接口,可作为双端队列使用,也作为栈使用
    • LinkedList 实现了 Cloneable 接口,可实现克隆
    • LinkedList 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输
  • LinkedList常用方法列表
    在这里插入图片描述
    在这里插入图片描述

Vector

  • 原理与 ArrayList 相同
  • 允许插入为空,允许插入重复数据
  • 线程安全 (采用 synchronized 同步实现)
  • Vector 与 ArrayList 类似,扩容是原大小的 2 倍,采用 synchronized 同步实现,因此开销就比 ArrayList 大
  • 可以使用 Collections.synchronizedList(); 得到一个线程安全的 ArrayList。也可以使用 concurrent 并发包下的 CopyOnWriteArrayList 类
  • 已过时

Set集合

TreeSet

  • 底层基于红黑树实现
  • 支持有序性操作,查找,删除,添加等操作都是基于红黑树
  • 不允许插入为空
  • 线程不安全
  • 查找时间复杂度为 O(logN)

HashSet

  • 底层基于哈希表实现
  • 不支持有序性操作,并且失去元素插入顺序信息
  • 允许插入为空,但是最多一个
  • 线程不安全
  • 查找时间复杂度:O(1)

LinkedHashSet

  • 继承自 HashSet,同时使用双向链表维护元素的插入顺序
  • 此链接列表定义了迭代顺序,即按照将元素插入到 set 中的顺序(插入顺序)进行迭代
  • LinkedHashSet是迭代有序的HashSet

Queue集合

LinkedList

  • 基于双向链表,可以用于实现双向队列

PriorityQueue

  • 基于堆结构实现,可以用于实现优先队列

Map集合

Hashtable

  • 基于哈希表实现
  • key、value 均不能为 null,且 key 不能重复,value 允许重复
  • 失去元素插入顺序信息
  • 线程安全 (采用 synchronized 同步实现)
  • 已过时

HashMap

  • 相当于STL的unordered_map
  • 基于哈希表实现
  • key、value 允许为 null,重复性:key 重复会覆盖,value 允许重复
  • 失去元素插入顺序信息
  • 线程不安全
  • capacity:默认 table 容量为 16,扩容时候保证为 2 的 n 次方
  • loadFactor:装载因子,默认是 0.75
  • Java8 之前:桶存储的是用链表。而 Java8 之后:链表长度大于 8时会将链表转换为红黑树
  • 常用方法列表
    在这里插入图片描述

LinkedHashMap

  • 基于双向链表实现
  • key、value 都允许为空,重复性:key 重复会覆盖, value 允许重复
  • 此链接列表定义了迭代顺序,该迭代顺序通常就是将键插入到映射中的顺序(插入顺序)。注意,如果在映射中重新插入键,则插入顺序不受影响
  • LinkedHashMap是迭代有序的HashMap
  • 线程不安全

TreeMap

  • 相当于STL的map
  • 基于红黑树实现
  • key 不能为 null,value 允许为空,重复性:key 重复会覆盖,value 允许重复
  • 根据 key 值进行排序
  • 线程不安全

Java多线程编程

Java线程属性

线程状态

  • 新建状态:
    • 使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。
  • 就绪状态:
    • 当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。
  • 运行状态:
    • 如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
  • 阻塞状态:
    • 如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:
      • 等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
      • 同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。
      • 其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
  • 死亡状态:
    • 一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。

线程优先级

  • 每一个 Java 线程都有一个优先级,这样有助于操作系统确定线程的调度顺序。
  • Java 线程的优先级是一个整数,其取值范围是 1 (Thread.MIN_PRIORITY ) - 10 (Thread.MAX_PRIORITY )。
  • 默认情况下,每一个线程都会分配一个优先级 NORM_PRIORITY(5)。
  • 具有较高优先级的线程对程序更重要,并且应该在低优先级的线程之前分配处理器资源。但是,线程优先级不能保证线程执行的顺序,而且非常依赖于平台。

Java Thread类重要方法

Thread对象调用方法

在这里插入图片描述

Thread静态方法

在这里插入图片描述

线程创建

  • Java 提供了三种创建线程的方法:
    • 通过实现 Runnable 接口
    • 通过继承 Thread 类本身
    • 通过 Callable 和 Future 创建线程

下面依次用代码实现这些创建方法

通过实现Runnable接口

  • 创建一个线程,最简单的方法是创建一个实现 Runnable 接口的类。为了实现 Runnable,一个类只需要执行一个方法调用 run(),声明如下
    public void run()
    
  • 通过重写该方法可以设置线程任务,重要的是理解的 run() 可以调用其他方法,使用其他类,并声明变量,就像主线程一样。在创建一个实现 Runnable 接口的类之后,你可以在类中实例化一个线程对象。Thread 定义了几个构造方法:
    Thread();
    Thread(Runnable target);
    Thread(ThreadGroup group, Runnable target);
    Thread(String name);
    Thread(ThreadGroup group, String name);
    Thread(Runnable target, String name);	
    Thread(ThreadGroup group, Runnable target, String name);
    Thread(ThreadGroup group, Runnable target, String name, long stackSize);
    	// 实际上面8个构造函数都是调用init方法进行线程初始化
    private 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值