小记-致自己

本文探讨了Java中泛型数组的限制及解决方案,并深入解析了DelayQueue的工作原理及其应用场景,如session超时管理和考试场景模拟。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.看ArrayList集合源码时,看到创建的底层数组是Object[]数组,而非范型数组,针对此问题查了些资料https://www.cnblogs.com/ixenos/p/5648519.html
通过代码验证居然无法创建,百度之,原来JAVA不支持泛型数组,因为数组在创建的时候必须知道内部元素的类型,而JAVA是通过擦除法实现,运行时类型参数会被擦掉。

  1. 不能(直接)创建泛型数组
  2. 泛型数组实际的运行时对象数组只能是原始类型( T[]为Object[],Pair< T >[]为Pair[] ),而实际的运行时数组对象可能是T类型( 虽然运行时会擦除成原始类型 )
  3. 一般解决方案:(泛型数组包装器):使用ArrayList收集泛型数组对象的对象元素,如ArrayList< T >、ArrayList< Pair< String >>
    将获得数组的行为,以及由泛型提供的编译期的类型安全。
    二.java 延时队列DelayQueue -摘自:https://www.cnblogs.com/sunzhenchao/p/3515085.html
    在学习Java 多线程并发开发过程中,了解到DelayQueue类的主要作用:是一个无界的BlockingQueue,用于放置实现了Delayed接口的对象,其中的对象只能在其到期时才能从队列中取走。这种队列是有序的,即队头对象的延迟到期时间最长。注意:不能将null元素放置到这种队列中。

Delayed,一种混合风格的接口,用来标记那些应该在给定延迟时间之后执行的对象。此接口的实现必须定义一个 compareTo 方法,该方法提供与此接口的 getDelay 方法一致的排序。

在网上也看到两个示例,但这两个示例个人在实际运行时均没有达到满足业务场景的效果,因而对其进行了修改,供大家参考讨论。
实际工作中,可应用在session超时管理,网络应答通讯协议的请求超时处理。

业务场景一:多考生考试
该场景来自于http://ideasforjava.iteye.com/blog/657384,模拟一个考试的日子,考试时间为120分钟,30分钟后才可交卷,当时间到了,或学生都交完卷了考试结束。

这个场景中几个点需要注意:

考试时间为120分钟,30分钟后才可交卷,初始化考生完成试卷时间最小应为30分钟
对于能够在120分钟内交卷的考生,如何实现这些考生交卷
对于120分钟内没有完成考试的考生,在120分钟考试时间到后需要让他们强制交卷
在所有的考生都交完卷后,需要将控制线程关闭
实现思想:用DelayQueue存储考生(Student类),每一个考生都有自己的名字和完成试卷的时间,Teacher线程对DelayQueue进行监控,收取完成试卷小于120分钟的学生的试卷。当考试时间120分钟到时,先关闭Teacher线程,然后强制DelayQueue中还存在的考生交卷。每一个考生交卷都会进行一次countDownLatch.countDown(),当countDownLatch.await()不再阻塞说明所有考生都交完卷了,而后结束考试。
注意⚠️
unit.convert(time - System.currentTimeMillis(), TimeUnit.MILLISECONDS)
第一个参数为数字,第二个参数为数字代表的时间单位,这里作为毫秒
执行convert后,返回unit当前的时间单位,此处是纳秒

如果第二个参数写成纳秒,
TimeUnit.NANOSECONDS,则这个转换函数转换前后数值相等,但是DelayQueue的take方法中
if (delay > 0) {
long tl = available.awaitNanos(delay);
}
等待的时间将缩短,上面的for循环重复执行将近原来的1000倍。这样会造成CPU空转,是load升高。

原型模式实际上就是实现Cloneable接口,重写clone()方法。
使用原型模式的优点:
● 性能优良
原型模式是在内存二进制流的拷贝,要比直接new一个对象性能好很多,特别是要在一个循环体内产生大量的对象时,原型模式可以更好地体现其优点。
● 逃避构造函数的约束
这既是它的优点也是缺点,直接在内存中拷贝,构造函数是不会执行的(参见13.4节)。
使用场景:
● 资源优化场景
类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。
● 性能和安全要求的场景
通过new产生一个对象需要非常繁琐的数据准备或访问权限,则可以使用原型模式。
● 一个对象多个修改者的场景
一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用。

浅拷贝和深拷贝:
浅拷贝:Object类提供的方法clone只是拷贝本对象,其对象内部的数组、引用对象等都不拷贝,还是指向原生对象的内部元素地址,这种拷贝就叫做浅拷贝,其他的原始类型比如int、long、char、string(当做是原始类型)等都会被拷贝。
注意: 使用原型模式时,引用的成员变量必须满足两个条件才不会被拷贝:一是类的成员变量,而不是方法内变量;二是必须是一个可变的引用对象,而不是一个原始类型或不可变对象。
深拷贝:对私有的类变量进行独立的拷贝
如:thing.arrayList = (ArrayList)this.arrayList.clone();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值