
线程
文章平均质量分 73
主要介绍线程相关知识
懒虫虫~
无论人生上到哪一层台阶,阶下有人在仰望你,阶上亦有人在俯视你。你抬头自卑,低头自得,唯有平视,才能看见真实的自己!
展开
-
利用Redisson分布式锁解决多服务器数据刷新问题
Component@Override// 拒绝将任务保存起来if (!@OverrideSystem.out.println("执行了TaskInfo的run方法,执行了某某业务逻辑");System.out.println("保存了被拒绝的任务:" + node);原创 2025-05-01 06:46:58 · 543 阅读 · 0 评论 -
【CompletableFuture实战】
过去的一年,匆匆忙忙,换了一次工作,写博客的习惯就落下了,总之,有点懈怠。希望今年能重拾信心,步入正规!CompletableFuture的用法网上资料颇多,我这里就简单记录下自己项目中的真实场景(代码模拟思路),算是抛砖引玉~return;//模拟某线程执行业务,比如创建用户});//模拟某线程执行业务,比如根据ID列表查询用户});//等待两个线程执行完毕,最后执行主线程。原创 2025-01-18 09:49:24 · 326 阅读 · 0 评论 -
利用Semaphore实现多线程调用接口A且限制接口A的每秒QPS为10
前段时间在群里面发现有个群友抛出一个实际需求:需要通过一个接口拉取数据,这个接口有每秒10QPS限制,请问如何实现数据拉去效率最大化且限制调用拉取接口每秒10PQPS?我觉得这个需求挺有意思的,跟某群友讨论,发现可以利用JUC包下的Semaphore实现,几行代码就能搞定。这里将实现方案做下整理,算是抛砖引玉吧~原创 2023-09-13 22:55:25 · 520 阅读 · 0 评论 -
多线程事务怎么回滚?
在Spring中可以使用@Transactional注解去控制事务,使出现异常时会进行回滚,在多线程中,这个注解则不会生效。如果主线程需要先执行一些修改数据库的操作,当子线程在进行处理出现异常时,主线程修改的数据则不会回滚,导致数据错误。通过使用sqlSession控制手动提交事务,可以达到主线程和子线程数据事务回滚。原创 2023-08-13 17:54:49 · 882 阅读 · 1 评论 -
【SpringBoot AOP Redis实现延时双删功能实战】
一、业务场景在多线程并发情况下,假设有两个数据库修改请求,为保证数据库与redis的数据一致性,修改请求的实现中需要修改数据库后,级联修改redis中的数据。请求一:A修改数据库数据 B修改redis数据请求二:C修改数据库数据 D修改redis数据并发情况下就会存在A ---> C ---> D ---> B的情况 (一定要理解线程并发执行多组原子操作执行顺序是可能存在交叉现象的)## 1、此时存在的问题 A修改数据库的数据最终保存到了redis中,C在A之后也修改了数据库数据。 此原创 2022-08-14 12:04:13 · 5388 阅读 · 11 评论 -
线程池:业务代码最常用也最容易犯错的组件
由于线程的创建比较昂贵,随意、没有控制地创建大量线程会造成性能问题,因此短平快的任务一般考虑使用线程池来处理,而不是直接创建线程。今天,我们就针对线程池这个话题展开讨论,通过三个生产事故,来看看使用线程池应该注意些什么。Java中的Executors类定义了一些快捷的工具方法,来帮助我们快速创建线程池。《阿里巴巴Java开发手册》中提到,禁止使用这些方法来创建线程池,而应该手动new ThreadPoolExecutor来创建线程池。这一条规则的背后,是大量血淋淋的生产事故,最典型的就是newFixedTh转载 2022-07-02 22:40:18 · 278 阅读 · 0 评论 -
启动线程为啥是start()而不是run()方法?
一、通过start和run两种方式验证启动差异package com.test.thread;public class ThreadStartTest { public static void main(String[] args) throws Exception{ System.out.println("*********run方式***启动一个线程**************************"); threadRun.run(); threadRun.join();/原创 2021-08-21 10:41:22 · 396 阅读 · 0 评论 -
控制多线程执行顺序
目标:创建4个线程分别为thread1,thread2,thread3,thread4让这三个线程依次执行。方法一:joinpublic class ThreadSequence { //线程1 ----------------------》 static Thread thread1 = new Thread(()->{ System.out.println(Thread.currentThread().getName()+"启动了------》");原创 2021-07-08 22:09:08 · 955 阅读 · 1 评论 -
ThreadLocal线程池使用和TransmittableThreadLocal值传递
一、ThreadLocal配合线程池注意配合remove方法,线程池是对线程进行复用的,如果没有及时的清理,那么之前对该线程的使用,就会影响到后面的线程了,造成数据不准确。package com.test.thread;import java.util.concurrent.ExecutorService;import java.util.concurrent.LinkedBlockingDeque;import java.util.concurrent.ThreadPoolExecutor;原创 2021-07-05 22:15:50 · 3080 阅读 · 3 评论 -
CountDownLatch、CyclicBarrier、Semaphore代码理解
一、CountDownLatch1.1 CountDownLatch1package com.zhang;import java.util.concurrent.CountDownLatch;public interface CountDownLatch1 { public static void main(String[] args) { CountDownLatch countDownLatch = new CountDownLatch(6); for原创 2021-07-01 22:51:57 · 115 阅读 · 0 评论 -
公平锁与非公平锁、可重用锁、自旋锁、读写锁代码验证
package com.zhang;import java.util.concurrent.TimeUnit;public class ReenterLockDemo { //synchronized和ReenterLock均为重用锁演示,其中synchronized是非公平锁,ReenterLock默认非公平锁 public static void main(String[] args) { Phone phone = new Phone(); ne原创 2021-06-30 23:02:25 · 967 阅读 · 0 评论 -
线程理解:三个线程交替顺序打印ABC
一、题目描述建立三个线程A、B、C,A线程打印10次字母A,B线程打印10次字母B,C线程打印10次字母C,但是要求三个线程同时运行,并且实现交替打印,即按照ABCABCABC的顺序打印这里参照网上方案,特此整理如下:1、使用synchronized, wait和notifyAll2、使用Lock->ReentrantLock 和 state标志3、使用Lock->ReentrantLock 和Condition(await 、signal、signalAll)4、使用AtomicI原创 2021-06-28 22:23:51 · 2339 阅读 · 0 评论 -
整理了4种创建多线程方式(代码实践)
Java多线程的实现方式有4种,分别是继承Thread类、实现Runnable接口、实现Callable接口。一、继承Thread类实现1、继承Thread类,并重写run方法/** * 继承Thread类,并重写run方法 */public class MyThread extends Thread { @Override public void run() { super.run(); System.out.println(原创 2021-05-25 08:44:51 · 370 阅读 · 1 评论 -
死锁编码及定位分析
一、死锁死锁是指两个或两个以上进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力干涉它们都将无法推进下去。二、死锁代码案例package com.zhang;import java.util.concurrent.TimeUnit;public class HoldLockThreadTest { public static void main(String[] args) { //调用实现了Runnable接口的类 String lock原创 2021-05-11 23:25:54 · 185 阅读 · 1 评论 -
手撕阻塞队列BlockingQueue
一、什么是阻塞队列BlockingQueue 继承了 Queue 接口,是队列的一种。当阻塞队列为空时,从队列中获取元素的操作将会被阻塞;当阻塞队列满了,往队列添加元素的操作将会被阻塞。在多线程中,阻塞的意思是,在某些情况下会挂起线程,一旦条件成熟,被阻塞的线程就会被自动唤醒。二、常见的BlockQueue方法根据插入和取出两种类型的操作,具体分为下面几些类型:抛出异常:这时候插入和取出在不能立即被执行的时候就会抛出异常。特殊值:插入和取出在不能被立即执行的情况下会返回一个特殊的值(tru原创 2021-05-09 15:32:32 · 398 阅读 · 0 评论 -
wait()、sleep()和yield()方法的区别
1、所属类不同:wait()是Object类中的非静态方法;sleep()、yield()是Thread类中的静态方法;也是Thread类中的静态方法。2、作用不同:wait()用于线程同步或者线程之间进行通信;sleep()用于休眠当前线程,并在指定的时间点被自动唤醒;yield()临时暂停当前正在执行的线程,来让有同样优先级的正在等待的线程有机会执行(如果等待的线程优先级较低,则当前线程继续执行)。3、释放资源:wait()会释放线程所占用的锁和管程;sleep()释放线程所占用的锁,但不释放管程;原创 2021-01-25 16:01:18 · 3275 阅读 · 1 评论 -
面试手写生产者和消费者(四种写法Synchronized、SynchronizedQueue、lock+Condition、BlockingQueue)
生产者消费者方式生产者生产产品,消费者消费,有产品可以消费,无则不可以要生产,生产一个消费一个。最好烂熟于心,能手写能讲原理,因为面试手写概率比较大,了解第三种将是面试的王牌,毕竟它涉及到了CAS,volite和BlockQueue的知识,将提高的价值!方式一:最经典的synchronized版本package com.ProCon;public class ProConTest1 { //这一种只需要在生产和消费方法加上sychronized锁就好了,然后生产完即通知消费即可,如果num原创 2021-01-18 19:23:45 · 1709 阅读 · 3 评论 -
volatile和synchronized比较
面试时很可能遇到这样一个问题:使用volatile修饰int型变量i,多个线程同时进行i++操作,这样可以实现线程安全吗?提到线程安全、线程同步,我们经常会想到两个关键字:volatile和synchronized,那么这两者有什么区别呢?1.volatile修饰的变量具有可见性volatile是变量修饰符,其修饰的变量具有可见性。可见性也就是说一旦某个线程修改了该被volatile修饰的变量,它会保证修改的值会立即被更新到主存,当有其他线程需要读取时,可以立即获取修改之后的值。在Java中为了加快转载 2020-11-16 15:24:30 · 277 阅读 · 0 评论 -
Java面试---AQS
AQS原理AQS:AbstractQuenedSynchronizer抽象的队列式同步器。是除了java自带的synchronized关键字之外的锁机制。AQS的全称为(AbstractQueuedSynchronizer),这个类在java.util.concurrent.locks包AQS的核心思想如果被请求的共享资源空闲,则将当前请求资源的线程设置为有效的工作线程,并将共享资源设置为锁定状态,如果被请求的共享资源被占用,那么就需要一套线程阻塞等待以及被唤醒时锁分配的机制,这个机制AQS是用CL转载 2020-11-13 17:09:33 · 765 阅读 · 0 评论 -
Java面试---锁
在笔者面试过程时,经常会被问到各种各样的锁,如乐观锁、读写锁等等,非常繁多,在此做一个总结。介绍的内容如下:乐观锁/悲观锁独享锁/共享锁互斥锁/读写锁可重入锁公平锁/非公平锁分段锁偏向锁/轻量级锁/重量级锁自旋锁以上是一些锁的名词,这些分类并不是全是指锁的状态,有的指锁的特性,有的指锁的设计,下面总结的内容是对每个锁的名词进行一定的解释。1.1 乐观锁/悲观锁乐观锁与悲观锁并不是特指某两种类型的锁,是人们定义出来的概念或思想,主要是指看待并发同步的角度。乐观锁:顾名思义,就是很乐观,转载 2020-11-12 17:37:19 · 134 阅读 · 0 评论 -
CAS原理机制分析
一、CASCAS是英文单词CompareAndSwap的缩写,中文意思是:比较并替换。CAS需要有3个操作数:内存地址V,旧的预期值A,将要更新的目标值B。CAS指令执行时,当且仅当内存地址V的值与预期值A相等时,将内存地址V的值修改为B,否则就什么都不做。整个比较并替换的操作是一个原子操作。二、案例分析1.普通多线程count自增运算CASTest1.javapackage com.cas;public class CASTest1 { public static int count =原创 2020-09-28 16:25:55 · 662 阅读 · 0 评论 -
多线程wait()、sleep()、yield()和join()方法的区别
一、介绍1. sleep()Thread.sleep(1000);在指定时间内让当前执行的线程暂停执行一段时间,让其他线程有机会继续执行,但不会释放对象锁,也就是说如果有synchronized同步快,其他线程仍然不能访问共享数据,不推荐使用,sleep() 使当前线程进入阻塞状态,在指定时间不会执行。2. wait()对象的方法,会释放对象锁wait()和notify()、notifyAll(),这三个方法用于协调多个线程对共享数据的存取,所以必须在synchronized语句块内使用也就是说原创 2020-09-26 15:49:01 · 2151 阅读 · 4 评论 -
深入理解Java并发之synchronized实现原理
在 Java 中,关键字 synchronized可以保证在同一个时刻,只有一个线程可以执行某个方法或者某个代码块(主要是对方法或者代码块中存在共享数据的操作),同时我们还应该注意到synchronized另外一个重要的作用,synchronized可保证一个线程的变化(主要是共享数据的变化)被其他线程所看到(保证可见性,完全可以替代Volatile功能)synchronized的三种应用方式synchronized关键字最主要有以下3种应用方式,下面分别介绍修饰实例方法,作用于当前实例加锁,进入同步转载 2020-09-16 21:09:21 · 233 阅读 · 0 评论 -
ThreadLocal解决SimpleDateFormat线程安全问题
ThreadLocal的应用场景之一就是可以解决SimpleDateFormat线程安全问题。一、SimpleDateFormat线程不安全原因SimpleDateFormat(下面简称sdf)类内部有一个Calendar对象引用,它用来储存和这个sdf相关的日期信息,例如sdf.parse(dateStr), sdf.format(date)诸如此类的方法参数传入的日期相关String,Date等等,都是交友Calendar引用来储存的。这样就会导致一个问题,如果你的sdf是个static的,那么多个原创 2020-09-11 10:09:34 · 3412 阅读 · 2 评论 -
Java 线程池
1:线程池优势(1)、降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗;(2)方便线程并发数的管控。因为线程若是无限制的创建,可能会导致内存占用过多而产生OOM,并且会造成cpu过度切换(cpu切换线程是有时间成本的(需要保持当前执行线程的现场,并恢复要执行线程的现场))。2:线程池ThreadPoolExecutor参数3:线程池执行流程4:参数详解代码如下:public ThreadPoolExecutor(int corePoolSize, int maximumP原创 2020-06-26 17:38:58 · 2096 阅读 · 0 评论 -
面试之ThreadLocal
在面试环节中,考察"ThreadLocal"的理解十分必要。常用的提问方式如下:“知道ThreadLocal吗?”“讲讲你对ThreadLocal的理解”当然了,也有面试官会慢慢引导到这个话题上,比如提问“在多线程环境下,如何防止自己的变量被其它线程篡改”等等。这篇文章主要从以下几个角度来分析理解1、ThreadLocal是什么2、ThreadLocal源码分析3、ThreadLocal内存泄漏问题及解决方案一、ThreadLocal是什么ThreadLocal即本地线程变量,它填充的变量转载 2020-05-22 18:16:37 · 3174 阅读 · 0 评论 -
为什么说单例模式的饿汉式是线程安全的?
类加载的方式是按需加载,且只加载一次。因此,在上述单例类被加载时,就会实例化一个对象并交给自己的引用,供系统使用。换句话说,在线程访问单例对象之前就已经创建好了。再加上,由于一个类在整个生命周期中只会被加载一次,因此该单例类只会创建一个实例。也就是说,线程每次都只能也必定只可以拿到这个唯一的对象。因此就说,饿汉式单例天生就是线程安全的。参考如下:原文链接:https://blog.csdn.net/Ricky_Monarch/article/details/99407326...原创 2020-05-20 10:05:56 · 13403 阅读 · 1 评论 -
Java获得多线程的返回结果方式
一:Java创建线程方式继承Thread类或者实现Runnable接口。但是Runnable 的 run() 方法是不带返回值的,那如果我们需要一个耗时任务在执行完之后给予返回值,应该怎么做呢?第一种方法:在 Runnable 的实现类中设置一个变量 V,在 run 方法中将其改变为我们期待的结果,然后通过一个 getV() 方法将这个变量返回。package com.test.thread;import java.util.*;import sun.swing.AccumulativeRun原创 2020-06-15 14:47:35 · 5853 阅读 · 0 评论