20220822学习内容 Collection接口和Lock接口

本文介绍了Java中集合框架的基础知识,包括数组和链表的特性,以及Collection接口作为集合框架的一部分,允许无序和重复元素。同时,文章详细讲解了Lock接口,对比了与synchronized的区别,并阐述了Lock的可重入、可中断和公平锁特性,以及常见方法的使用。
摘要由CSDN通过智能技术生成

 程序=算法(解决问题的步骤)+数据结构(合理的持有数据)
  如何衡量算法的优劣?
  1、计算时间
          long start=System.currentTimeInMills();
       处理步骤;
      long end=System.currentTimeInMills();
      System.out.println("该算法用时"+(end-start)+"ms");
  2、时间复杂度
  是一个用于度量一个算法的运算时间的一个描述,本质是一个函数,根据这个函数能在不用具体的测试数据来测试的情况下,粗略地估计算法的执行效率
  
 查找一个算法中执行次数最多的部分和算法规模的相互关系--函数
 常用大O来表述,这个函数描述了算法执行所要时间的增长速度

  常量阶    O(1)
  对数阶    O(logn)
  线性阶    O(n)
  线性对数阶    O(nlogn)
  n方阶    O(nⁿ)
  指数阶    O(2ⁿ)
  阶乘阶    O(n!)

数组:

存储区间是连续的,占用内存严重,故空间复杂度很大。但数组的二分查找(前提是必须有序)
 时间复杂度小,为O(logN);
 数组的特点是
 - 寻址容易(arr[n]=arr[0]+n*每个元素的长度,时间复杂度为O(1))
 - 插入和删除困难(可能会引发一半以上的数据元素移动,时间复杂度为O(n));
- Java中的数组是定长的,如果需要变长则需要自行编程实现

链表:

存储区间离散(数据不是连续存放的),占用内存比较宽松,故空间复杂度很小,
  但时间复杂度很大O(N)。
 链表的特点是:
  - 寻址困难(可能需要通过遍历的方式查找元素,时间复杂度为O(n))
 - 插入和删除容易(不需要引发元素的移动,仅仅只是进行地址的拷贝,时间复杂度为O(1))。

 Java集合类存放于 java.util 包中,是一个用来存放对象的容器

  - 集合只能存放对象。比如存一个int型数据1放入集合中,其实它是自动转换成
 Integer 类后存入的(装箱操作),Java中每一种基本类型都有对应的引用类型
  - 集合存放的是多个对象的引用,对象本身还是放在堆内存中
  - 集合可以存放不同类型,不限数量的数据类型。定义集合变量时如果不指定数据类型
 ,则默认数据类型为Object

   数组和集合的比较
 针对Java中的数组定长,Java提出了集合框架,实现了一种变长存储数据的容器---集合
数组不是面向对象的,存在明显的缺陷,集合弥补了数组的缺点,比数组更灵活更实用,
 而且不同的集合框架类可适用不同场合。如下:
 - 数组能存放基本数据类型和对象,而集合类存放的都是对象的引用,而非对象本身
 - 数组容量固定无法动态改变,集合类容量动态改变
 - 数组无法判断其中实际存有多少元素,length只告诉了数组的容量,而集合的size()
  可以确切知道元素的个数
  - 集合有多种实现方式和不同适用场合,不像数组仅采用顺序表方式
- 集合以类的形式存在,具有封装、继承、多态等类的特性,通过简单的方法和属性即可
 实现各种复杂操作,大大提高了软件的开发效率

 Iterator迭代器
 Iterator迭代器:走访器,可以理解为集合中元素的指针
 它是Java集合的顶层接口(不包括map系列的集合,Map接口是map系列集合的顶层接口) 

public interface Iterator<E> {
    boolean hasNext();  判断是否有后续元素
   E next(); 指针向后移动,同时返回指向的数据
  default void remove() {  删除指针所指向的元素
         throw new UnsupportedOperationException("remove");
   }
  使用lambda表达式的方式遍历所有元素
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
 Iterable接口用以表示实现类是可以迭代的
  Iterator<T> iterator();

 顶级接口Collection:无序、允许重复

 public interface Collection<E> extends Iterable<E>一般说Collection是集合
 框架的顶级接口,但是事实上并不是顶级接口

 提供的方法:

int size();  获取集合中的元素个数   区分容积和元素个数

boolean isEmpty()判断集合中的元素个数是否为0

注意:只判断是否没有元素,但是并不判断集合对象是否为null

boolean contains(Object o)用于判断集合中是否包含对象 

boolean add(Object o)用于向集合中追加元素o,成功true失败false

boolean remove(Object o)删除集合中的指定元素o,成功true失败false

Iterator<E> iterator();获取迭代器,通过迭代器遍历集合中的每个元素

Object[] toArray();将集合转换为数组

void clear();删除集合中的所有元素
 

Lock接口:

java中提供了两种不同的方式加锁,synchronized和juc包下的Lock接口。

sychronized可重入、不可中断、非公平;Lock可重入、可中断、非公平和公平;

Lock是java 1.5中引入的线程同步工具,它主要用于多线程下共享资源的控制。
- 需要用户主动释放锁
- 可中断,设置超时中断
- 默认也是非公平锁,可以设置成公平锁
- 锁绑定多个condition用来精确唤醒

常见方法:
void lock();尝试获取锁,获取成功则返回,否则阻塞当前线程
void lockInterruptibly() throws InterruptedException;尝试获取锁,线程在
成功获取锁之前被中断,则放弃获取锁,抛出异常
boolean tryLock();尝试获取锁,获取锁成功则返回true,否则返回false
boolean tryLock(long time, TimeUnit unit)尝试获取锁,若在规定时间内获取到
锁,则返回true,否则返回false,未获取锁之前被中断,则抛出异常
void unlock();释放锁,一般需要使用try/finally结构保证锁的释放

 Lock有三个实现类

一个是ReentrantLock,另两个是ReentrantReadWriteLock
 类中的两个静态内部类ReadLock和WriteLock。这些类的底层使用都依赖于juc包
 抽象队列同步器AbstractQueuedSynchronizer

 使用方法:多线程下访问(互斥)共享资源时, 访问前加锁,访问结束以后解锁,
 解锁的操作推荐放入finally块中。
 private static final ReentrantLock lock=new ReentrantLock();  定义锁对象
 在具体方法中

 lock.lock();  
 try{
         代码块;
 }finally{
         lock.unlock();
 } 

  Condition接口是一个可以带条件的线程通知接口,需要和Lock锁一起使用,
  用于实现比Object类种线程通知方法更精细的控制  wait/notify/notifyAll
  方法:
  await()类似于Object种的wait方法
  signal()类似于Object中的notify方法
 应用场景:线程如果不满足某个Condition将被暂停挂起,而等到线程满足条件时被唤醒

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值