JAVA进阶
文章平均质量分 78
JAVA进阶
执键行天涯
国企程序猿 5年工作经验
展开
-
【JAVA高级】如何使用Redis加锁和解锁(二)做分布式锁案例(防误删锁)
在Java中,如果你使用Spring Boot并集成了Spring Data Redis,那么redisTemplate是一个常用的操作Redis的模板类。unlock方法则使用了一个Lua脚本来执行解锁操作,该脚本首先检查Redis中存储的锁的值是否与客户端提供的值相匹配,如果匹配则删除锁。如果不匹配,则返回0,表示解锁失败(非锁的持有者)。使用Redis中加锁和解锁的开发中,解锁需要验证当前客户端是否是锁的持有者,然后再解锁,具体怎么验证,下面是一个示例(使用redisTemplate来实现)原创 2024-09-26 17:50:16 · 626 阅读 · 9 评论 -
【JAVA高级】如何使用Redis加锁和解锁(一)、Lua脚本执行原理及流程
在Redis中加锁和解锁通常是通过Redis的原子性命令来实现的,以保证操作的原子性和线程安全。原创 2024-09-26 14:47:48 · 1338 阅读 · 0 评论 -
【JAVA高级】 redis分布式双重加锁(业务校验:防止接口并发调用时数据重复)
@TOC]背景:在日常开发过程中,遇到了一个需求,比如有一个对象User(name,age、sex)有三个属性,现在需要用户新增接口中,防止此接口被多人同时请求访问,产生了姓名&年龄相同的,还有年龄&性别相同的数据;原创 2024-09-26 12:34:37 · 1255 阅读 · 2 评论 -
【JAVA高级】ReadWriteLock 读写锁
🌹🌹期待您的关注 🌹🌹,让我们共同进步!ReentrantReadWriteLock可重入读写锁是读写锁的唯一实现。多个线程同时读一个资源类没有任何问题,所以为了满足并发量,读取共享资源应该可以同时进行。但是,如果有一个线程想去写共享资源类,就不应该再有其他线程可以对该资源进行读或写。原创 2024-09-06 10:28:02 · 280 阅读 · 0 评论 -
【JAVA高级】Semaphore信号量的使用介绍
而Semaphore可以解决这个问题,比如6辆车3个停车位,对于CountDownLatch只能停3辆车,而Semaphore可以停6辆车,车位空出来后,其它车可以占有,这就涉及到了Semaphore.accquire()和Semaphore.release()方法。● acquire(获取) 当一个线程调用acquire操作时,它要么通过成功获取信号量(信号量减1),要么一直等下去,直到有线程释放信号量,或超时。信号量主要用于两个目的,一个是用于多个共享资源的互斥使用,另一个用于并发线程数的控制。原创 2024-09-06 10:19:28 · 316 阅读 · 0 评论 -
【JAVA高级】并发同步工具CyclicBarrier 的使用介绍
CyclicBarrier 是 Java 中的另一个同步辅助类,它可以让一组线程互相等待,直到所有线程都达到一个屏障点后再继续执行。与CountDownLatch 不同的是,CyclicBarrier的计数器可以循环使用,当所有线程都到达屏障点后,计数器会重置,可以被复用。所谓 Cyclic 即循环的意思,所谓 Barrier即屏障的意思。所以综合起来,CyclicBarrier 指的就是循环屏障,虽然这个叫法很奇怪,但是却能很好地表达其含义。原创 2024-09-05 18:41:44 · 1233 阅读 · 0 评论 -
【多线程】线程池之exectue与submit的区别
背景:在日常进行多线程的开发过程中,遇见了有的线程池用excute提交子线程任务,有的使用submit提交线程任务。execute和submit都属于线程池的方法,那这两种有什么区别呢?我们一起来验证一下。原创 2024-09-04 10:01:37 · 544 阅读 · 0 评论 -
【多线程】CountDownLatch的简单实现
通过上一篇对CountDownLatch的使用,我们也明白了他的基本原理,接下来我们一起来实现一个CountDownLatch的基础效果。原创 2024-09-03 17:22:28 · 307 阅读 · 0 评论 -
【多线程】Java并发工具类之CountDownLatch 同步协作的利器
CountDownLatch用一个给定的计数器来初始化,该计数器的值表示需要等待完成的任务数量。当计数器的值达到零时,表示所有需要等待的任务都已经完成,此时在CountDownLatch上等待的线程将被唤醒并可以继续执行。● 其它线程调用countDown方法会将计数器减1(调用countDown方法的线程不会阻塞),当计数器的值变为0时,因await方法阻塞的线程会被唤醒,继续执行。CountDownLatch内部维护了一个计数器,只有当计数器==0时,某些线程才会停止阻塞,开始执行。原创 2024-09-03 14:41:34 · 1629 阅读 · 5 评论 -
【多线程】线程间通信 之虚假唤醒和中断
两个线程,可以操作初始值为0的一个变量,实现一个线程对该变量+1,一个线程对该变量-1,实现交替,来10轮,变量初始值为0,以实现此问题作为引入,简化我们的理解。原创 2024-09-02 17:39:38 · 780 阅读 · 0 评论 -
【多线程】并发编程wait和sleep的区别
wait():wait()方法必须在同步方法或同步代码块中调用,因为它要求调用线程必须拥有对象的锁。wait():调用wait()方法的线程会释放它持有的对象锁,并进入等待状态,直到其他线程调用该对象的notify()或notifyAll()方法来唤醒它。wait():wait()方法被调用后,可以通过其他线程调用该对象的notify()或notifyAll()方法来唤醒。sleep():sleep()方法睡眠指定时间之后,线程会自动苏醒,或者通过调用interrupt()方法提前打断睡眠。原创 2024-09-02 16:09:18 · 306 阅读 · 0 评论 -
【线程间通信】sleep/wait/notify/notifyAll作用及使用
wait和notify都要先获取到锁才能使用。获取到锁后,使用wait,线程会先释放锁对象,然后阻塞等待;使用notify,会通知在同一个锁对象上等待的线程,如果当前有多个线程在等待同一个锁对象,会随机唤醒一个等待的线程;而notifyAll,是所有线程都唤醒,这些线程再一起竞争锁。原创 2024-09-02 14:17:21 · 899 阅读 · 0 评论 -
线程安全性分析 及 成员变量、实例变量、局部变量、类变量的区别及存储
静态变量前要加static关键字,而实例变量前则不加。原创 2024-08-27 10:27:30 · 1849 阅读 · 6 评论 -
【流式编程】Stream.of()用法解析及使用示例
Stream.of() 方法可以接受任意数量的参数,这些参数将作为流中的元素。你可以传递任意类型的参数给这个方法,只要所有参数的类型相同,或者它们之间存在适当的自动装箱/拆箱关系。在这个示例中,我们首先使用 Stream.of() 创建一个整数流,然后使用 filter() 方法过滤出偶数,最后使用 sum() 方法计算这些偶数的和。这个示例创建了一个包含四个字符串的流,并使用 forEach 方法打印出流中的每个元素。中的一个静态方法,用于从给定的元素创建一个顺序流(Sequential。原创 2024-08-26 17:55:25 · 646 阅读 · 0 评论 -
【JAVA流编程】Arrays.stream(T[] array) 用法
使用流,你可以进行复杂的查询/过滤操作、映射转换、归约等操作,而这一切都可以以声明式的方式完成,代码更加简洁、易于理解。假设你有一个整型数组,你想要找出其中所有的偶数,并计算它们的和。Arrays.stream() 函数可以将数组转换为流,使用流API可以更简洁的处理数组中的数据,在大量数据的情况下可以提高性能。使用 Arrays.stream() 方法可以将数组转换为流,然后就可以对数组中的元素进行各种操作,例如过滤,映射,排序等。引入的一个非常有用的方法,它允许你以流(Stream)的形式处理数组。原创 2024-08-26 17:47:58 · 220 阅读 · 0 评论 -
【Java并发】变量的内存存储、线程安全分析
也就意味着不同作用域的局部变量是不共享的。UserDaoImpl中的update方法中的 conn 是局部变量,并且没有逃离方法的作用范围,所以 conn是线程安全的,UserServiceImpl 中的 UserDao是成员变量,但是userDao它调用的方法是线程安全的,所以userDao也是线程安全的,同理,userService也是线程安全的。conn是成员变量,多个线程用的是同一个conn,所以是线程不安全的,同时 userDao 也是线程不安全的,userService也是线程不安全的。原创 2024-08-26 17:41:16 · 935 阅读 · 0 评论