
Java进阶篇
文章平均质量分 91
Java进阶篇
无限循环者
世上唯一不能复制的是时间,唯一不能重演的是人生。该怎么走,过什么样的生活,全凭自己的选择和努力。
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
Java—注解机制详解
元注解是 Java 中用于注解自定义注解的注解,主要由 Sun 公司提供。它们可以控制自定义注解的应用范围和行为。元注解包括以下四种:@Target用于指定自定义注解可以应用于哪些 Java 元素。其默认值为任何元素。ElementType.CONSTRUCTOR:用于描述构造器。ElementType.FIELD:用于描述成员变量、对象、属性(包括 enum 实例)。ElementType.LOCAL_VARIABLE:用于描述局部变量。ElementType.METHOD:用于描述方法。原创 2024-09-24 21:23:27 · 1484 阅读 · 0 评论 -
Java—反射机制详解
反射(Reflection)是Java语言中的一种机制,它允许程序在运行时检查和操作类、接口、字段和方法等类的内部结构。通过反射,你可以在运行时获取类的信息,包括类的构造器、字段、方法等,并且可以在运行时动态地创建对象、调用方法、访问或修改字段。原创 2024-09-24 20:36:23 · 955 阅读 · 0 评论 -
SpringBoot Aop 详解
AOP是一种编程范式,它通过将横切关注点(如日志、安全、事务等)从主要业务逻辑中分离,降低模块间的耦合度,提升代码的可重用性和可维护性。AOP可以看作是对传统面向对象编程(OOP)的补充,尤其是在处理那些跨多个类的公共逻辑时。前置通知(@Before):在目标方法调用之前执行。适用于执行前的准备工作,如日志记录、权限检查等。System.out.println("目标方法即将被调用");后置通知(@After):在目标方法完成之后执行,不论目标方法是否成功。通常用于清理工作或收尾日志。原创 2024-09-22 16:40:51 · 954 阅读 · 0 评论 -
Java设计模式全面解析
适配器模式是一种有效的设计模式,用于解决由于接口不兼容而导致的类之间无法协作的问题。通过适配器的引入,可以在不改变现有类的情况下,灵活地实现接口之间的适配和转换。原创 2024-09-22 10:16:50 · 1181 阅读 · 0 评论 -
Java中ArrayList和LinkedList的比较
关于 ArrayList 和 LinkedList 在添加 (add) 和删除 (remove) 操作上的性能比较,传统观点认为由于 ArrayList 需要移动数据,而 LinkedList 只需调整链表指针,因此 LinkedList 更快。然而,实际性能并不是这么简单,两者在不同情况下的表现差异较大,在Java中,ArrayList和LinkedList都是常用的列表实现类,它们都实现了List接口,但在内部工作原理和性能方面有显著差异。原创 2024-09-20 16:22:44 · 1161 阅读 · 0 评论 -
MybatisPlus 快速入门
是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。特性无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求支持 Lambda 形式调用。原创 2024-09-09 19:31:30 · 1410 阅读 · 0 评论 -
MyBatis 快速入门
JDBC适合对性能有严格要求的应用,或者需要高度自定义 SQL 的场景,但缺乏框架支持,开发维护难度较大。Hibernate 和 JPA更适合需要快速开发且数据库操作较为标准化的场景,适合使用 ORM 的优势,但可能在处理复杂查询时性能和灵活性受限。MyBatis提供了 SQL 和业务逻辑的清晰分离,适合需要复杂 SQL 查询并希望有较高性能控制的场景,同时开发效率较 JDBC 更高,但不及 Hibernate 和 JPA。原创 2024-09-07 20:43:40 · 1205 阅读 · 0 评论 -
Java的Cookie和Session配合解决会话管理问题
HttpSession是一种在服务器端保留更多信息的技术,它为每个客户端(浏览器)在服务器端创建一个唯一的session对象,用于跟踪客户端的状态信息。3、也可以通过HttpSession的API 对最大闲置时间进行设定,通过调用 setMaxInactiveInterval(int interval) 方法,可以设置会话的最大闲置时间,单位为秒。需要注意的是,session也是域对象,这意味着可以在其中存储各种类型的数据,并在整个会话期间共享和访问这些数据。原创 2024-04-04 17:39:33 · 875 阅读 · 0 评论 -
Java中关于ArrayList集合的练习题
【代码】Java中关于ArrayList集合的练习题。原创 2023-11-28 22:26:34 · 338 阅读 · 0 评论 -
Java的ArrayList中关于删除的常用操作及方法
在这个示例中,我们创建了一个自定义的ArrayList子类Main,它继承了ArrayList,并添加了一个新的方法removeElementsInRange(int fromIndex, int toIndex)。> c)方法时,它会遍历列表中的每个元素,并将其与集合c中的每个元素进行比较。该方法会删除列表中索引为index的元素,并将其后面的元素往前移动一位,填补被删除的元素位置。然后使用remove(int index)方法删除了索引为1的元素(即第二个元素),并打印出被删除的元素以及操作后的列表。原创 2023-11-23 23:04:57 · 3505 阅读 · 0 评论 -
Java进阶篇--线程池之FutureTask
另外,通过ExecutorService的submit()方法也可以返回一个FutureTask对象,然后可以通过FutureTask.get()或者FutureTask.cancel方法获取结果或取消任务的执行。1、未启动状态:指的是在创建FutureTask后,但尚未执行FutureTask.run()方法之前,FutureTask处于未启动状态。2、已启动状态:指的是FutureTask.run()方法正在被执行的过程中,此时FutureTask处于已启动状态。FutureTask的。原创 2023-11-08 15:42:14 · 962 阅读 · 0 评论 -
Java进阶篇--线程池之ScheduledThreadPoolExecutor
ScheduledThreadPoolExecutor简介ScheduledThreadPoolExecutor简介ScheduledThreadPoolExecutor继承自ThreadPoolExecutor(),并实现了ScheduledExecutorService接口,因此它同时具备了线程池的基本功能和任务调度的功能。ScheduledThreadPoolExecutor可以用来延迟执行任务或者周期性执行任务,相比于传统的Timer类,其功能更加强大和灵活。原创 2023-11-07 16:32:01 · 1497 阅读 · 0 评论 -
Java进阶篇--Executors类创建常见线程池
具体来说,newFixedThreadPool 创建的线程池会维护一个固定数量的工作线程,当有任务提交时,会使用其中一个工作线程来执行任务。需要注意的是,虽然该线程池只使用单个工作线程来执行任务,但仍然可以通过 ExecutorService 提供的方法提交多个任务,这些任务会按照提交的顺序被放入队列,并由单个工作线程逐个执行。要配置一个线程池是比较复杂的,尤其是对于线程池的原理不是很清楚的情况下,很有可能配置的线程池不是较优的,因此在Executors类里面提供了一些静态工厂,生成一些常用的线程池。原创 2023-11-07 12:05:51 · 392 阅读 · 0 评论 -
Java进阶篇--线程池之ThreadPoolExecutor
线程池可以提高并发任务的执行效率和线程资源的利用率,通过合理设置线程池的大小和饱和策略,可以更好地适应系统的负载情况,提高系统的稳定性和性能。阻塞队列起到了任务缓冲的作用,当线程池中的线程都在执行任务时,新提交的任务会被暂存到阻塞队列中,等待线程池中的线程空闲下来再执行。线程池的饱和策略是在队列和线程池都满载的情况下,决定如何处理新提交的任务。当调用shutdown()方法时,线程池的状态会被设置为SHUTDOWN,此时线程池将不再接受新的任务提交,但会继续执行已提交的任务,直到所有任务执行完成。原创 2023-10-24 09:41:08 · 554 阅读 · 0 评论 -
Java进阶篇--LockSupport
每个使用LockSupport的线程都会与一个许可关联,如果该许可可用,并且可在线程中使用,则调用park()将会立即返回,否则可能阻塞。最后,释放锁并结束本次生产。这个示例展示了如何使用 LockSupport 和条件变量实现生产者-消费者模式,确保生产者在队列满时等待,消费者在队列空时等待,并通过条件变量进行线程的唤醒操作。在以上代码中,queue 是一个用于存储数据的队列,lock 是一个可重入锁,notFull 和 notEmpty 分别是条件变量,用于控制生产者和消费者的等待和唤醒操作。原创 2023-10-23 17:26:51 · 135 阅读 · 0 评论 -
Java进阶篇--Condition与等待通知机制
总的来说,Condition的实现依赖于底层的锁机制和等待队列,通过等待队列实现了线程的等待和唤醒,通过锁机制实现了线程同步和互斥。当一个线程调用await()方法时,会释放锁并进入等待状态,并且将当前线程加入到等待队列中。而当其他线程调用signal()或signalAll()方法时,会从等待队列中取出一个节点,并将其转移到同步队列中,并唤醒对应的线程。而当其他线程调用Condition的signal()或signalAll()方法时,会从等待队列的头部取出一个节点,并将其转移到锁的同步队列中。原创 2023-10-23 11:05:39 · 1362 阅读 · 0 评论 -
Java进阶篇--并发容器之ArrayBlockingQueue与LinkedBlockingQueue
它提供了put、take等方法来实现元素的添加和移除,并且在队列为空或已满时能够自动阻塞和唤醒相应的线程,以保证生产者和消费者之间的同步和协作。总之,ArrayBlockingQueue 是一种高效、线程安全的数据结构,适用于多线程环境下的生产者-消费者问题,其中生产者线程负责将元素插入队尾,消费者线程负责从队首取出元素进行处理。如果队列不为空,则获取并移除数据,并通知生产者线程。在这个例子中,我们使用了多个生产者和消费者线程,它们同时操作LinkedBlockingQueue,展示了队列的并发性质。原创 2023-10-23 09:20:38 · 2278 阅读 · 0 评论 -
Java进阶篇--并发容器之BlockingQueue
然后我们使用peek()方法查看队列的头部元素,使用poll()方法删除队列的头部元素,最后使用element()方法再次查看队列的头部元素。根据队列的状态和操作结果,会输出相应的信息。阻塞队列的特点是,当队列为空时,消费者线程将被阻塞,直到队列中有新的元素;同时,由于BlockingQueue的特殊性,它还提供了阻塞等待和超时等待的功能,使得在多线程环境中的数据交换更加方便和安全。总而言之,BlockingQueue是一种线程安全的容器类,通过提供阻塞等待的操作,可以简化线程间的协作和数据交换。原创 2023-10-22 17:40:04 · 244 阅读 · 0 评论 -
Java进阶篇--并发容器之ThreadLocal内存泄漏
改进和优化ThreadLocal内存泄漏的原因?ThreadLocal是为了解决多线程共享访问对象带来的线程安全问题。它通过为每个线程分配一个对象实例,达到隔离的目的,使得线程之间互不影响。与同步机制不同的是,同步机制以时间换空间,控制线程访问共享对象的顺序,而ThreadLocal则是为每个线程分配一个对象实例,牺牲了空间效率换来时间效率。原创 2023-10-22 11:01:37 · 893 阅读 · 0 评论 -
Java进阶篇--并发容器之ThreadLocal
ThreadLocalMap中的每个元素都是一个Entry对象,Entry包含了线程局部变量的键值对,其中键是ThreadLocal对象,值是线程局部变量的值。Entry内部还包含了一些相关的操作方法,例如get()方法获取线程局部变量的值,set()方法设置线程局部变量的值等。总结一下,ThreadLocal的实现原理就是通过每个线程维护一个ThreadLocalMap,使用ThreadLocal实例作为key,将值存储在ThreadLocalMap中,实现了线程间的隔离和数据的独立访问。原创 2023-10-21 15:58:50 · 235 阅读 · 0 评论 -
Java进阶篇--并发容器之CopyOnWriteArrayList
也就是说,即使两个读线程同时读取同一个集合,它们也可能看到的是不同的数据,这是因为写线程在执行完毕后,只会通知正在执行的读线程去切换到新的数组上。4、通过使用 volatile 修饰数组引用,在写操作中将新的数组分配给数组引用之后,根据 volatile 的 happens-before规则,对读线程来说,对数组引用的修改是可见的。因此,Copy-On-Write(COW)容器可以被视为一种读写分离的思想的实现,通过针对不同的数据容器进行写操作,放弃数据的实时性以达到数据最终一致性的目标。原创 2023-10-20 18:41:31 · 233 阅读 · 0 评论 -
Java进阶篇--并发容器之ConcurrentLinkedQueue
具体来说,当tail指向的节点的下一个节点不为null时,会执行定位队列真正的队尾节点的操作,并通过CAS操作完成tail的更新;当head指向的节点的item域为null时,会执行定位队列真正的队头节点的操作,并通过updateHead方法完成head的更新。具体来说,tail的更新被延迟至插入节点之后,只有当tail指向的节点的下一个节点不为null时才会进行真正的队尾节点定位和更新操作。当需要从队列中删除元素时,我们需要使用head指针指向的节点作为要删除的节点,并通过CAS操作将其指向下一个节点。原创 2023-10-20 14:55:04 · 506 阅读 · 0 评论 -
Java进阶篇--并发容器之ConcurrentHashMap
具体来说,ConcurrentHashMap将哈希表分为多个段(Segment),每个段都是一个独立的哈希表,且对于每个段的操作都是线程安全的。put方法是向ConcurrentHashMap中插入一个键值对,它首先会对key进行hash计算得到一个桶的位置,在该桶的位置上加锁,然后查找当前桶中是否已经存在该key,如果存在则替换掉原有的value,否则将该键值对插入到桶中。需要注意的是,在ConcurrentHashMap中,Node类型的元素是作为数组的元素存储的,因此需要使用位运算来计算内存地址。原创 2023-10-19 20:27:34 · 470 阅读 · 0 评论 -
Java进阶篇--读写锁
而当某个线程需要更新共享数据时,需要获取写锁,此时所有的读线程和其他写线程都会被阻塞,保证数据的一致性。按照锁降级的规则,持有写锁的线程可以首先获取读锁,然后再释放写锁,以将写锁降级为读锁,不支持锁升级。读写锁的使用可以提高程序的并发读取能力,减少读操作之间的互斥等待,从而提高程序的性能和响应速度。需要注意的是,锁降级是允许的,因为读锁是共享的,多个线程可以同时持有读锁。需要注意的是,读锁与写锁是互斥的,即当存在一个线程持有写锁时,其他线程无法同时获取读锁或写锁。最后,在释放写锁之前,执行读操作。原创 2023-10-17 18:22:30 · 2934 阅读 · 0 评论 -
Java进阶篇--死锁
其中一个线程先获取 resource1,另一个线程再获取 resource1,这样能够保证资源的获取顺序是一致的,避免了循环等待。需要注意的是,以上方法并非适用于所有情况,具体的应用需要根据具体的需求和场景来选择合适的策略。为了避免死锁,我们采取了避免持有并请求条件的策略,即一个线程只能在释放所有资源之后再请求新的资源。这样能够确保资源的占用和释放是一致的,不会出现死锁的情况。注意,在上面的示例中,为了能够观察到死锁和避免死锁的效果,我们需要等待线程执行完成。以下是同时包含死锁和避免死锁的代码示例,原创 2023-10-16 18:21:58 · 231 阅读 · 0 评论 -
Java进阶篇--可重入锁 & 不可重入锁
可重入锁允许同一线程多次获得锁,而不可重入锁则不支持同一个线程多次获得锁。在这个示例中,我们创建了一个可重入锁对象 reentrantLock 和一个不可重入锁对象 nonReentrantLock ,并在 ReentrantTask 和 NonReentrantTask 类中分别使用这两种类型的锁来实现线程同步。NonReentrantTask 类使用不可重入锁,在 run() 方法中获取不可重入锁并进入临界区域执行操作,但是如果尝试再次获取相同的锁,将被阻塞。可重入锁是一种支持重进入的锁机制。原创 2023-10-16 09:00:17 · 3963 阅读 · 0 评论 -
Java进阶篇--AQS(AbstractQueuedSynchronizer)
"),并输出读取的数据。在上面的示例中,我们创建了一个 ReentrantLock 对象作为独占锁,并实现了两个线程对该锁的获取和释放操作。AQS的核心思想是使用一个整形的state值来表示同步状态,state的语义由具体的同步器决定,可以表示锁的可重入次数、资源的数量等。值得注意的是,在获取独占锁的过程中,如果该锁已经被其他线程占用,则当前线程会被阻塞,直到锁可用时才会继续执行。请注意,在实际开发中,应该根据具体情况设计和实现独占锁的逻辑,并考虑线程安全、性能和可扩展性等方面的问题。原创 2023-10-15 21:48:19 · 216 阅读 · 0 评论 -
Java进阶篇--乐观锁 & 悲观锁
2、悲观锁(Pessimistic Locking): 悲观锁的思想是,假设并发的事务之间经常产生冲突,因此在操作数据时会先将其锁定,以防止其他事务对数据进行修改。乐观锁的优点是并发性能较高,不需要阻塞其他事务的执行,但是在并发冲突较多的情况下,需要频繁地回滚和重试,可能会影响性能。悲观锁的优点是保证数据的一致性,不会出现并发冲突的情况,但是会导致并发性能较低,因为其他事务需要等待锁的释放才能执行。乐观锁和悲观锁是在并发编程中用于处理数据一致性和并发控制的两种不同的策略。原创 2023-10-15 15:21:45 · 743 阅读 · 1 评论 -
Java进阶篇--公平锁 & 非公平锁
Java进阶篇--公平锁 & 非公平锁原创 2023-10-15 10:49:44 · 4151 阅读 · 1 评论 -
并发编程之并发关键字篇--final
在这两个方法中,我们采用了“锁住final对象,访问可变状态”的模式,即通过synchronized (map)语句块,锁住map对象,确保并发访问时只有一个线程可以访问该map对象,从而保证了线程安全性。总的来说,对于final修饰的域,在构造函数内的写操作不会被重排序到构造函数之外,并确保在构造函数完成之前对其他线程可见。但是,在某些情况下,特别是在X86处理器上,由于它的内存模型较强(内存访问按照程序顺序执行),可能会省略一些内存屏障,因为X86不会对写-写重排序,也不会对有间接依赖性的操作重排序。原创 2023-10-09 22:36:13 · 347 阅读 · 0 评论 -
并发编程之并发关键字篇--volatile
需要注意的是,在并发编程中,使用volatile需要谨慎,必须熟悉它的特性和使用场景,否则可能会产生意外的结果。这使得其在多线程并发编程中成为一种简单有效的同步手段,但需要注意的是,volatile 并不能保证原子性,如果需要原子操作,仍需配合其他机制,如锁或原子类。当线程B执行volatile读操作时,它会从主内存中获取flag的最新值,并且会使得线程B的本地内存中flag的值有效。对 volatile 变量的读操作先行发生于后续的任意线程的写操作,这保证了其他线程修改后的最新值对该变量的读取操作可见。原创 2023-10-09 19:48:27 · 170 阅读 · 0 评论 -
并发编程之并发关键字篇--synchronized
当锁处于这个状态下,其他线程试图获取锁时,都会被阻塞住,当持有锁的线程释放锁之后会唤醒这些线程,被唤醒的线程就会进行新一轮的夺锁之争。当一个线程尝试获得锁时,会将对象头中的Mark Word复制到线程栈帧中的一个用于存储锁记录的空间,并使用CAS(Compare and Swap)操作将对象头中的Mark Word替换为指向锁记录的指针。当多个线程竞争同一个锁时,除了第一个成功获取锁的线程外,其他线程都会进入阻塞状态,等待持有锁的线程释放锁。当一个线程尝试获得锁时,会进入阻塞状态,等待锁被释放。原创 2023-10-09 10:40:52 · 310 阅读 · 0 评论 -
并发编程之并发理论篇--as-if-serial规则和happens-before规则的区别
而happens-before规则是保证多线程环境下操作顺序性和可见性的机制,确保操作执行的先后顺序和对共享数据的修改在不同线程之间正确传递,适用于多线程环境下的同步操作。根据JMM的规定,如果一个操作A happens-before另一个操作B,那么操作A的执行结果对操作B可见,并且操作A的执行顺序在操作B之前。as-if-serial规则确保了单线程程序的执行结果不会被改变,即在单线程环境下,程序的执行顺序应当按照代码的顺序来执行,而不会受到编译器和处理器的重排序的影响。原创 2023-10-08 16:19:10 · 448 阅读 · 0 评论 -
并发编程之并发理论篇--重排序与数据依赖性
值得注意的是,这种数据依赖性仅适用于单个处理器内执行的指令序列和单个线程内部的操作,不考虑不同处理器之间和不同线程之间的数据依赖性。编译器重排序的具体过程与处理器重排序有所不同,但目标是优化程序的性能和并行度,同时遵循as-if-serial规则,即程序的执行结果不能改变。指令级别重排序:处理器可以对指令进行乱序执行,即不按照程序中的顺序依次执行指令,而是按照指令之间的数据依赖关系和可并行性进行重排序。总之,重排序过程是处理器在执行阶段对指令或内存操作的顺序进行重新排序的过程,旨在提高程序的性能和效率。原创 2023-10-08 09:48:22 · 302 阅读 · 0 评论 -
Java进阶篇--网络编程
常见的网络协议族包括TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/英特网互联协议)、UDP协议(User Datagram Protocol,用户数据报协议)、ICMP协议(Internet Control Message Protocol,Internet 控制报文协议)、HTTP、FTP、SMTP等。TCP在传输数据之前,需要在通信双方之间建立连接,保存对方的信息,并交换一些连接参数,这些参数通常包含在TCP头部中。原创 2023-09-29 17:46:12 · 353 阅读 · 0 评论 -
并发编程之并发理论篇--内存模型
可见性保证了一个线程对共享变量的修改对其他线程是可见的,即当一个线程修改了共享变量的值后,其他线程能够立即看到最新的值。通过理解JMM的规则以及主内存和工作内存之间的交互机制,开发者可以采取适当的同步手段,如使用锁、volatile关键字、原子类等,来实现线程安全的程序设计,避免数据不一致性和竞态条件的问题。然而,请注意,由于编译器无法找到最优的指令插入位置,JMM采取了保守策略,为每个volatile写操作和读操作插入不同类型的内存屏障,以最大程度地确保volatile内存语义的正确实现。原创 2023-09-24 17:24:10 · 184 阅读 · 0 评论 -
Java常见面试题(含答案,持续更新中~~)
Java常见面试题(含答案,持续更新中~~)原创 2023-09-17 20:57:40 · 968 阅读 · 2 评论 -
Java--面试技巧
我们在找工作时,需要结合自己的现状,针对意向企业做好充分准备。作为程序员,你有哪些面试IT技术岗的技巧?你可以从以下几个方向谈谈你的想法和观点。方向一:分享你面试IT公司的小技巧方向二:IT技术面试有哪些常见的问题?方向三:分享总结遇到过的面试题--请简单描述一下Java的面向对象的三大特性:封装、继承和多态。原创 2023-08-30 16:27:54 · 244 阅读 · 0 评论 -
Java进阶篇--HttpClient工具类
处理其他与 HTTP 消息传输相关的功能:HttpClient 主要关注的是发送和接收 HTTP 消息,对于一些与 HTTP 消息传输相关的功能,如身份验证、缓存、代理等,HttpClient 可能需要配合其他库或配置来实现。总之,HttpClient 是一个强大的 HTTP 客户端库,主要用于发送和接收 HTTP 消息。HttpClient 支持 HTTP/1.1 和 HTTP/2 协议,实现了所有 HTTP 的方法(GET,POST,PUT,DELETE 等),支持自动转向,支持代理服务器,支持。原创 2023-08-31 16:00:09 · 1679 阅读 · 0 评论 -
Java进阶篇--泛型
此外,Java 泛型的类型参数只能是类类型(包括 Class、接口类型或枚举类型),不能是数组类型或函数类型。这样,在 MyBox 类中,我们可以直接使用 Integer 作为类型参数,而不必重新定义一个新的类型参数。你可以在类的定义中使用 T 来表示泛型,然后在方法中使用 T 来表示任何类型的对象。在上述代码中,我们定义了一个泛型方法 getFirst,它接受一个 List 类型的参数,并返回一个 T 类型的对象。泛型的基本语法是在类、接口或方法名的后面加上尖括号(< >),并在其中定义类型参数。原创 2023-08-28 21:40:52 · 1025 阅读 · 0 评论