自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

孙广明的博客

Keep running. Keep learning.

  • 博客(33)
  • 收藏
  • 关注

原创 Redis哨兵模式工作原理

这个过程也是基于Redis的发布订阅实现的,哨兵是一个Redis Sentinel实例(是一个特殊的Redis实例,不具备常规的读写能力),除了具备监控、选主、通知能力,他还支持发布订阅功能。:hello”频道,并在该频道上发布自己的IP和端口信息,并订阅该频道上其他哨兵发布的IP和端口信息,通过获取到的IP和端口信息,实现与其他哨兵建立连接,相互通信。哨兵通过向主库发送INFO命令,主库会将所有从库的IP和端口信息返回给哨兵,哨兵获取到所有的从库的IP和端口之后,便可以和从库建立连接。

2024-03-09 17:37:13 719

原创 遇见 Kafka

遇见 Kafka ~

2022-08-25 15:24:04 450 1

原创 结合Redis在Spring架构体系中使用雪花算法

前言分布式ID生成策略有多种,各有利弊。这里记录下在工作中我结合Redis在Spring架构体系中使用雪花算法生成分布式ID的方式。一、代码部分import lombok.extern.slf4j.Slf4j;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.stereotype.Service;import javax.annotation.PostConst.

2021-11-06 22:38:48 3689 1

原创 Jdk 动态代理

文章目录一、简介一、简介在Java中,包含两种动态代理:基于Jdk的动态代理基于Cglib的动态代理两种动态代理的主要区别:Jdk动态代理生成的代理对象会默认继承Proxy类,Java是单继承多实现,因此它是基于接口的动态,也就是说代理类至少需要实现一个接口。Cglib的动态代理是基于类的动态代理。在学习Springframework 的 AOP模块时,其核心就是动态代理,如果Bean实现了某个接口,那么默认使用的基于Jdk的动态代理,如果Bean没有实现任何接口,那么使用的是Cg

2021-04-09 12:32:58 138

原创 Dokcer部署Redis服务器

文章目录前言一、安装Docker二、通过Docker部署Redis前言记录下自己在通过Docker部署Redis时遇到的那些坑一、安装Docker通过访问Docker官网可以清楚的了解怎么安装:Docker官网连接阿里云也有教程教你怎么安装各类环境,如下截图:这里我使用的是Centos 8,简单的记录下安装过程:step1: 安装Docker依赖库$ yum install -y yum-utils device-mapper-persistent-data lvm2step2

2021-03-26 23:10:12 185

原创 MySQL事务

-- --------------------------------------------------------------------------------------------------------- 事务-- --------------------------------------------------------------------------------------------------------- 事务是指一组原子性的SQL语句。-- ACID: 原子性(ato

2021-01-04 09:36:17 69

原创 Hello! Socket.

Hello! Socket.import java.io.ByteArrayOutputStream;import java.io.InputStream;import java.net.ServerSocket;import java.net.Socket;/** * @author : sungm * @date : 2020-11-10 */public class Server { public static void main(String[] args) {

2020-11-10 15:35:51 242 1

原创 [Java 集合] 1. 基本概念

文章目录一、概述二、Collection三、Map一、概述集合:Java 集合类存放于java.util 包中,是一个用来存放对象的容器。注意点:集合只能存储对象。如果存一个int类型的数据,其实是自动转换成Integer类型后存入的。集合存放的是多个对象的引用,对象本身还是存储在堆内存中。集合可以存放不同类型、不限数量的数据类型。Java中的集合类主要包含两大类:CollectionMap二、Collection三、Map...

2020-09-07 22:24:59 104

原创 [Java 集合] 3. Iterable 接口

文章目录一、概述二、Iterable2.1 forEach() 方法2.2 iterator() 方法2.3 spliterator () 方法三、Iterator 与 Iterable 的区别一、概述与 Iterator 接口不同,Iterable 是 java.lang 包中定义的一个接口,表示可迭代的。Java.util.Collection 接口继承了 Iterable 接口,这就意味着所有Collection子类都要重写Iterator 接口中定义的抽象方法。二、Iterable如下

2020-09-07 22:21:49 184

原创 [Java 集合] 2. Iterator 接口

文章目录一、概述二、Iterator2.1 haseNext() 方法2.2 next() 方法2.3 remove() 方法2.4 forEachRemaining(Consumer<? super E> action) 方法三、ListIterator四、迭代器的性能一、概述Iterator是 java.util 包下定义的一个接口,表示迭代器。如下:Java 8 中已知的子接口包括:ListIteratorPrimitiveIterator<T,T_CONS>

2020-09-07 22:17:23 269

原创 [Java 并发编程] 23. CAS算法

文章目录一、CAS一、CASCAS (Compare And Swap的缩写) 算法是在设计并发程序时常用的一个算法。通常情况下, CAS 算法接收两个入参,一个期望值,一个修改值,如果期望值与实际值相同,那么将修改值赋予指定值。听起来CAS算法很复杂,实际上当你理解它之后就变得非常简单。在JUC提供的Lock的实现类中,大量的使用了CAS算法,比如ReentrantLock,大致算法如下:public void compareAndSwap(int expect, int update) {

2020-09-07 21:56:24 77

原创 [Java 并发编程] 22. 线程池

文章目录一、线程池二、自定义线程池一、线程池当我们需要限制一个应用程序中同一时间运行的线程数量,我们通常使用线程池来实现。通过把任务传递给线程池,只要线程池中有空闲的线程就将空闲的线程分配任务并执行任务,而不是给每个任务都创建一个新的线程。任务被插入到阻塞队列中,当线程池存在空的线程时,阻塞队列中的任务就被分配到空闲的线程中执行。自Java 5 开始,java.util.concurrent 包中提供了线程池,比如:java.util.concurrent.ExecutorService.二、

2020-09-07 21:54:52 79

原创 [Java 并发编程] 21. 阻塞队列

文章目录一、阻塞队列(Blocking Queues)二、BlockingQueues的实现一、阻塞队列(Blocking Queues)Blocking Queues 是当你尝试从一个空队列取出一个元素时、或尝试从一个满队列做插入一个元素时会被阻塞的队列。包含:一个线程尝试从空队列做出队操作时会被阻塞,直到其他线程插入一个元素至队列中。一个线程尝试从满队列做入队操作时会被阻塞,直到其他线程消耗队列中的一个或多个元素、或清空队列。Java 5 提供了 java.util.concurr

2020-09-07 21:53:04 264

原创 [Java 并发编程] 20. Semaphores

文章目录前言一、简单的 Semaphore二、使用 Semaphore三、Semaphore 计数四、有限 Semaphore五、Semaphore 当成Lock使用前言Semaphores(信号)是一个线程同步结构,它既可以用于线程通信以避免丢失信号,也可以像锁一样使关键代码(介于lock和unlock之间的代码)在多个线程之间同步运行。Java 5 提供了 java.util.concurrent.Semaphore 类,所以你可以不需要自己实现 Semaphore,但我们需要知道它的原理并使用

2020-09-07 21:50:34 148

原创 [Java 并发编程] 19. Read/Write Lock

文章目录前言一、Java 实现 Read/Write Lock二、可重入 Read / Write Lock2.1 读可重入(读 -> 读)2.2 写可重入(写 -> 写)2.3 读-写可重入(读 -> 写)2.4 写-读可重入(写 -> 读)2.5 全功能读写可重入锁2.6 在finally代码块中调用unlock()方法前言读写锁比其他同步锁要更加复杂一些。多个线程读相同的共享资源不会引发线程安全问题,所以允许共享资源被多个线程同时访问。但是如果有一个线程在写某个资源,需要

2020-09-07 21:48:03 101

原创 [Java 并发编程] 18. Lock

文章目录前言一、简单的Lock二、锁重入三、公平锁四、在finally代码块中调用unLock()方法前言Lock 是除synchronized代码块的另外一种线程同步机制,Lock可以具有比synchronized代码块更复杂的作用。Lock可以使用synchronized关键字,所以它并不能让我们摆脱synchronized关键字。自JDK 5开始,java.util.concurrent.locks包提供了一些Lock的实现类,比如ReentrantLock、ReadWriteLock、Con

2020-09-05 11:39:33 127

原创 [Java 并发编程] 17. 饥饿与公平

文章目录前言一、Java 中常见饥饿的场景1.1 高优先性的线程比低优先性的线程更容易获取CPU时间片1.2 线程无限期阻塞等待进入synchronized代码块1.3 线程调用了wait方法,一直未被唤醒二、Java 中实现公平2.1 使用Lock代替synchronized代码块前言一个线程没有获取到CPU时间片,因为CPU时间片总是被其他线程获取,这种情况我们叫它“饥饿”。线程被“饿死”是因为没有获取CPU时间片执行指令。解决“饥饿”的办法成为“公平” —— 所有的线程公平的获取CPU时间片执行

2020-09-05 11:35:13 186

原创 [Java 并发编程] 16. 死锁和预防死锁

文章目录一、线程死锁二、数据库死锁三、预防死锁3.1 锁排序3.2 锁超时3.3 锁排序 vs. 锁超时3.4 死锁检测3.5 预防死锁小结一、线程死锁死锁:两个或多个线程因为竞争资源而造成的一种僵局。示例:线程A拥有锁a,线程B拥有锁b,线程A尝试获取锁b,线程B尝试获取锁a,因此产生死锁。线程A将永远无法获取锁b,同样线程B也无法获取锁a。Thread A locks a, wait for bThread B locks b, wait for a说明:线程A和线程B必须分

2020-09-05 11:32:58 167

原创 [Java 并发编程] 15. 线程通信

文章目录一、通过共享对象实现线程通信二、Busy Wait三、等待通知机制:wait()、notify()、notifyAll()四、丢失信号五、虚假唤醒六、当多个线程等待同一个信号一、通过共享对象实现线程通信线程通过在共享对象中发送一个信号实现与其他线程通信。如下图所示,设置一个成员变量 hasProcess,线程A通过setHasProcess同步方法设置hasProcess的值,这样线程B可以读取到成员变量hasProcess的值,实现线程之间的通信。public class MySignal

2020-09-05 11:29:17 155

原创 [Java 并发编程] 14. ThreadLocal

文章目录前言一、创建一个线程变量二、设置 ThreadLocal 的值三、获取 ThreadLocal 的值四、移除 ThreadLocal 的值五、ThreadLocal 泛型前言Java的ThreadLocal类能够让我们创建各个线程独有的线程变量,这个线程变量只有创建它的线程可以对它做读写操作。即使两个线程执行同一段代码,并且这个代码引用了同一个ThreadLocal变量,这两个线程也不能访问彼此的ThreadLocal变量。因此,Java 的 ThreadLocal 类以一种非常简单的方式确保

2020-09-05 11:26:22 119

原创 [Java 并发编程] 13. volatile关键字

文章目录前言一、volatile 可见性问题二、volatile 可见性保证2.1 所有变量可见性保证三、指令重排挑战四、volatile happens-before 保证五、volatile 不足六、什么时候使用 volatile ?七、volatile 性能考虑前言volatile 关键字用来标记一个 Java 变量被保存至主内存中。更确切的说:每次读取 volatile 变量时会从主内存中读取,而不是从CPU高速缓存中读取;每次写 volatile 变量时会把数据写回主内存中,而不是CPU高速

2020-09-05 11:23:34 88

原创 [Java 并发编程] 12. synchronized关键字

文章目录一、synchronized 同步机制二、synchronized 关键字2.1 作用于普通方法2.2 作用于静态方法2.3 作用于代码块2.3.1 this对象作为synchronized同步代码块的锁2.3.2 class对象作为synchronized同步代码块的锁2.3.3 其他对象作为synchronized同步代码块的锁2.3.4 Lambda 表达式中的同步代码块三、synchronized 数据可见性四、synchronized 和指令重排五、什么对象用来做同步对象锁?六、synch

2020-09-05 11:16:50 109

原创 [Java 并发编程] 11. Java Happen Before Guarantee

文章目录前言一、指令重排二、指令重排在多CPU计算机中的问题三、volatile 可见性保证3.1 volatile 修改数据可见性保证3.2 volatile 读取数据可见性保证3.3 volatile happens-before 保证四、synchronized 可见性保证4.1 synchronized 锁进入可见性保证4.2 synchronized 锁退出可见性保证4.3 synchronized happens-before guarantee前言Java Happen Before G

2020-09-05 11:09:19 201 1

原创 [Java 并发编程] 10. Java内存模型

文章目录前言一、Java Memory Model二、计算机硬件内存结构三、桥接Java内存模型和计算机硬件内存结构3.1 共享数据的可见性3.2 竞争条件前言Java Memory Model(JMM: Java内存模型)提到 Java Virtual Machine(JVM: Java虚拟机) 如何与计算机内存工作。JVM是整个计算机模型,所以它包含JMM。如果你想要设计出正确的并发程序,那么理解JMM是非常重要的。Java内存模型会提到一个线程怎样获取被别的线程修改后的共享变量的值;也会提到当

2020-09-05 11:03:00 76

原创 [Java 并发编程] 9. 线程安全和不变性

文章目录一、线程安全和不变性一、线程安全和不变性竞争条件只发生在多个线程同时访问相同资源,并且存在一个或多个线程修改了共享资源,如果多个线程只读共享资源那么不会产生竞争条件。下面我们通过一个实例来说明当一个共享资源被多个线程访问,但没有线程修改共享资源时不会产生竞争条件。public class ImmutableValue{ private int value = 0; public ImmutableValue(int value){ this.value = value;

2020-09-05 10:54:02 142

原创 [Java 并发编程] 8. 线程安全和共享资源

文章目录前言一、Local variables (本地变量/局部变量)二、Local Object References (本地对象引用/局部对象引用)三、Object Member Variables (对象成员变量)四、线程安全规则前言线程安全:代码同时被多个线程安全地调用。如果一段代码是安全的,那它不包含竞争条件。竞争条件只发生在多个线程更新共享资源的时候,因此当Java线程执行的时候,知道哪些资源是线程共享资源是非常重要的。一、Local variables (本地变量/局部变量)局部变

2020-09-03 21:50:14 103

原创 [Java 并发编程] 7. 竞争条件和临界区

竞争条件是临界区可能发生的一种特殊状况。临界区是为了避免多线程产生并发问题而让多个线程顺序执行的那一段代码(我查阅了很多资源,对比了一些博客网站,对临界区的描述各不一致,这里只是我对临界区的一种理解,如果您有更好的描述,请告知小弟)。...

2020-09-03 21:46:45 77

原创 [Java 并发编程] 6. 创建和开始Java线程

文章目录前言一、创建和开始线程二、Thread 子类三、实现 Runnable 接口3.1 Java 类实现 Runnable 接口3.2 Java 匿名类实现 Runnable 接口3.3 Lambda 表达式实现 Runnable 接口3.4 开启一个实现了 Runnable 接口的线程四、使用哪种方式创建线程更好?五、常见陷阱:调用 run() 代替 start()六、 线程名(Thread Names)七、Thread.currentThread()八、暂停线程九、停止一个线程前言一个Java

2020-09-03 21:44:46 174

原创 [Java 并发编程] 5. 并发和并行

文章目录一、Concurrency 并发二、Parallelism 并行三、Concurrency vs. Parallelism一、Concurrency 并发应用程序中(Application)同时进行一个以上的任务(Task)。对于单CPU的电脑而言,不可能同时进行一个以上的任务,CPU通过交换的执行任务直到任务都被执行完成。二、Parallelism 并行应用程序中的任务(Task)被切割成多个子任务(SubTask)同时执行。实现并行你的应用程序必须有多个线程在同时执行,并且至少有一

2020-09-02 17:06:27 86

原创 [Java 并发编程] 4. 相同线程

文章目录前言一、为什么用单线程系统?二、相同线程(单线程系统的扩展)三、不共享状态(数据)前言相同线程是一个从单线程系统扩展到多个相同的单线程的系统的并发模型,结果是多个相同的线程在计算机中并行执行。一个相同线程的系统不是纯粹的单线程系统,因为它包含多个线程,每个线程执行就像一个单线程系统,所以用相同线程或者同一线程命名更加合理。一、为什么用单线程系统?你可能会想为什么每个人都能设计出单线程系统。单线程系统受欢迎的原因是因为单线程系统的并发模型比多线程系统的并发模型更加简单。单线程系统线程之间

2020-09-02 17:00:26 122

原创 [Java 并发编程] 3. 并发模型

文章目录前言一、并发模型与分布式系统相似二、共享状态 vs 隔离状态2.1 共享状态2.2 隔离状态三、并发模型3.1 Parallel Workers (并行工作者并发模式)3.2 Assembly Line (流水线并发模式)前言我们可以通过使用不同的并发模型来实现一个并发系统,线程之间通过协作完成系统给定的任务。不同的并发模型以不同的方式切割任务,线程之间可能存在通信和合作完成不同的任务。一、并发模型与分布式系统相似在一个并发系统中,不同的线程之间相互通信。在一个分布式系统中,不同的进

2020-09-01 18:58:38 164

原创 [Java 并发编程] 2. 使用多线程的成本

文章目录前言一、成本1.1 更复杂的程序设计1.2 上下文切换的开销1.3 减少上下文切换前言从单线程应用程序到多线程应用程序不仅仅需要考虑多线程应用程序更加高效,我们还需要考虑使用多线程的成本。使用多线程技术时不要仅仅因为你会使用多线程技术,你应该有一个更好的想法,比如更好的处理线程安全问题,以及多线程使用成本。尽可能的去测试多线程应用程序的性能以及响应速度,而不是靠猜想。一、成本更复杂的程序设计上下文切换的开销1.1 更复杂的程序设计在某些情况下,一个多线程应用程序比单线程应用程

2020-08-28 16:49:37 114

原创 [Java 并发编程] 1.并发和多线程

1. 并发和多线程并发编程并发编程涵盖了多线程技术在内,指并发执行任务时可能出现的问题,使用的多线程技术,以及解决方案。多线程:同一个应用程序中,多个线程同时执行。多线程应用程序:多线程应用程序是一个多 CPU 同时执行不同的线程的应用程序。如图一个线程不等于一个CPU,通常情况下一个CPU在不同时间段交换执行不同的线程,不同的CPU同时执行不同的线程。如图:2. 为什么使用多线程更好的利用单 CPU 资源更好的利用多 CPU 或 CPU 内核更快速的响应-提高用户体验更公

2020-08-26 17:19:25 289

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除