自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(192)
  • 收藏
  • 关注

原创 Spring与线程安全

Spring中的Bean默认是Singleton的,这并不是线程安全的,之所以大多时候没有出现线程安全问题,是因为这些Bean是无状态的,无状态的Bean在任何情况下都是线程安全的;也就是说,Spring并不负责线程的安全问题;Spring中用到的DTO,VO,Controller,Service,Dao这些都是无状态的Bean;如果多个线程需要对...

2019-03-31 23:01:00 78

原创 多线程并发最佳实践

多线程并发最佳实践使用本地变量;使用不可变类,可以降低代码中同步数量;最小化锁的作用于范围,阿姆达尔定律(安达尔定理):S = 1 / (1 - a + a/n),a代表并行计算部分所占的比例,n代表并行处理的节点个数,S代表加锁比;当a = 1时,只有串行没有并行,加锁比等于n;使用线程池的Executor,而不是直接new Thread执行;...

2019-03-31 22:51:00 99

原创 死锁

死锁两个或两个以上的进程在执行过程中,因争夺资源而造成的一种相互等待的状况,如果没有外力作用,它们将无法推进下去,此时的状态称为死锁状态;永远互相等待的进程称为死锁进程;科学家聚餐问题是个典型的死锁问题;死锁发生必须具备的4个条件互斥条件:进程对所分配到的资源进行排他性的使用;请求和保持条件:进程已经保持了至少1个资源,但又提出了新的资源...

2019-03-31 21:45:00 125

原创 线程池示例(二)Executors.newScheduledThreadPool(1)

示例1 - 延迟执行import lombok.extern.slf4j.Slf4j;import java.util.Date;import java.util.Timer;import java.util.TimerTask;import java.util.concurrent.Executors;import java.util.co...

2019-03-31 17:49:00 3410

原创 线程池示例(一)

示例1 - Executors.newCachedThreadPool()import lombok.extern.slf4j.Slf4j;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;@Slf4jpublic class T...

2019-03-31 17:38:00 102

原创 线程池 基础

new Thread弊端每次new Thread都要新建对象,性能差;通过new Thread创建的线程缺乏统一管理,可能会无限制的新建线程,相互竞争,有可能占用过多系统资源导致死机或OOM;缺少更多功能,比如更多的执行,定期执行,线程中断;线程池的好处重用存在的线程,减少对象创建,消亡的开销,性能好;可有效的控制最大并发线程数,提高系统...

2019-03-31 16:38:00 84

原创 J.U.C之BlockingQueue

BlockingQueue不仅拥有队列的完整功能,在多线程条件下,还管理多线程间的自动等待,唤醒等功能;在某些情况下对阻塞队列的访问可能造成阻塞,被阻塞的情况主要有2种:当一个线程试图对一个已经满了的队列进行入队操作,其将被阻塞,除非有另一个线程做了出队列操作;当一个线程试图对一个空队列进行出队操作,其将被阻塞,除非有另一个线程做了入队列操作;...

2019-03-31 12:50:00 84

原创 J.U.C之Fork/Join框架

Fork/Join框架Java7中引入的,用于进行并行执行任务的框架;其把大任务分割成若干个小任务,最后汇总各个小人物结果,得到大任务结果的框架,和MapReduce的思想非常类似;其实现算法是“工作窃取”,其大致思想是,把大任务拆成若干小任务,以队列为单位组织小任务,每个队列对应一个线程执行它,当有线程将自己队列中的小任务执行完成后,会去别的线程...

2019-03-31 11:55:00 108

原创 J.U.C之FutureTask

FutureTask类FutureTask不是AQS的子类;Java创建线程有2种方式,继承Thread和实现Runnable,这2种方式的缺陷是线程执行完成后,没法获取结果,Callable,Future和FutureTask可以;FutureTask的父类是RunnableFuture,RunnableFuture继承了Runnable和Fut...

2019-03-31 11:22:00 91

原创 J.U.C之Lock ReentrantLock“生出”的Condition

Condition概述整个协作过程是线程节点在AQS和condition的等待队列中来回移动实现的;Condition作为一个条件类,很好的维护了condition条件队列;Condition是个在多线程间协调的通信类;等待的线程被唤醒之后重新争夺锁;Condition相对于其他同步组件,使用还是复杂一些;实际开发中使用的很少;Condit...

2019-03-30 00:37:00 63

原创 J.U.C之Lock 总结

选择锁时的考量当只有少量竞争者的时候,synchronized是一个很好的通用的锁实现,而且synchronized不会引发死锁,JVM会自动解锁;竞争者不少,但线程的增长是可以预估的,ReentrantLock是一个很好的通用的锁实现;注意:选择锁的时候并不是最高级的才是最好的,适合自己使用场景的才是最好的; ...

2019-03-30 00:34:00 136

原创 J.U.C之Lock StampedLock

StampedLock概述StampedLock控制锁有3种模式:写,读,乐观读;其状态由版本和模式2个部分组成;锁获取方法返回的是一个数字作为票据, 其用相关的锁状态表示并控制相关的访问,数字0表示没有写锁被授权访问;在读锁上分悲观锁和乐观锁,乐观读指的是读的操作很多,写的操作很少,我们可以乐观的认为写入和读取同时发生的几率很小,因此不悲观的使...

2019-03-29 23:57:00 66

原创 J.U.C之Lock ReentrantReadWriteLock

ReentrantReadWriteLock概述其最核心要求:在没有任何读写锁的时候,才可以取得写入锁;其可以用于实现了悲观读取,如果我们执行中,进行读取时,经常可能有另一个执行要写入的需求,为了保持同步,ReentrantReadWriteLock的读取锁就可以排上用场了;如果读取执行情况很多,写入很少的情况下,ReentrantReadWrit...

2019-03-29 20:52:00 76

原创 J.U.C之Lock ReentrantLock & 锁

Java中的锁Java中的锁大体分2类;synchronized修饰的锁;J.U.C中提供的锁,其中核心的就是ReentrantLock;ReentrantLock (可重入锁) 和synchronized区别可重入性锁的实现synchronized依赖于JVM实现,好比操作系统控制实现,很难看到源码;ReentrantLock是J...

2019-03-29 20:30:00 94

原创 J.U.C之AQS CyclicBarrier

CyclicBarrier概述允许多个线程相互等待,直到到达某个公共屏障点(Common Barrier Point),只有当每个线程都准备就绪后,才能各自往下执行后面的操作;其和CountDownLatch相似的地方是都是通过计数器实现;当某个现场调用await()后,该线程就进入等待状态,而且计数器执行加1操作,当计数器达到了设置的初始值,调用...

2019-03-29 19:59:00 89

原创 J.U.C之AQS Semaphore

Semaphore概述信号量,可以控制并发访问的线程个数;可以很容易的控制某个资源被同时访问的个数;就很像三峡大坝对流量的控制;Semaphore使用场景用于仅能提供优先访问的资源,比如数据库的连接,最大只有20;Semaphore示例(一) 1次拿1个许可对要做并发控制的代码,前有要包裹上Semaphore相关的函数;控制同时只...

2019-03-29 18:41:00 94

原创 J.U.C之AQS CountDownLatch

CountDownLatch概述阻塞当前线程功能;初始化的时候指定了计数器的值,多线程对计数器的值的操作是原子性的,同时只能有一个线程操作其中计数器的值;调用该类的await()方法的线程会一直处于阻塞状态,直到其他线程调用countDown(),将当前计数器的值减为0,每次调用countDown()的时候,计数器的值减1,当计数器的值减为0时,所...

2019-03-29 18:09:00 66

原创 J.U.C之AQS 基础

AQS - AbstractQueuedSynchronizerAQS是java.util.concurrent.locks.AbstractQueuedSynchronizer的简写,是J.U.C包中最核心的类;提供了一个队列(FIFO),这个队列可以作为构建锁或者其他同步装置的基础;底层是双向链表Sync Queue,head节点主要用于后续调...

2019-03-29 16:12:00 90

原创 并发容器 J.U.C(二)ConcurrentHashMap& ConcurrentSkipListMap

和线程不安全容器的对应关系HashMap -> ConcurrentHashMapTreeMap -> ConcurrentSkipListMapConcurrentHashMap概述不允许空值;针对读做了大量的优化,具有非常高的并发性;ConcurrentHashMap示例import com.example.concu...

2019-03-29 14:28:00 78

原创 并发容器 J.U.C(二)CopyOnWriteArraySet & ConcurrentSkipListSet

与线程不安全的集合类的对应关系HashSet -> CopyOnWriteArraySetTreeSet -> ConcurrentSkipListSetCopyOnWriteArraySet概述底层实现依赖于CopyOnWriteArrayList,因此也适合于数据量很小的,读操作大于写操作的集合;迭代器不支持可变的remov...

2019-03-29 14:19:00 198

原创 并发容器 J.U.C(一)CopyOnWriteArrayList

J.U.C其实就是JDK提供的一个包:java.util.concurrentCopyOnWriteArrayList相较于ArrayList,CopyOnWriteArrayList是线程安全的;在添加新元素时,先将数组拷贝一份,在新数组中写,写完在把引用指向新数组;CopyOnWriteArrayList的add操作是在锁的保护下进行的...

2019-03-29 14:02:00 57

原创 同步容器 示例(三) Collections.synchronizedList() & Collections.synchronizedSet() & Collections.synchroni......

Collections中相关同步方法示例用这些同步方法创建出来的集合对象是线程安全的;import com.example.concurrency.annotations.ThreadSafe;import com.google.common.collect.Lists;import com.google.common.collect.Sets...

2019-03-29 10:58:00 452

原创 同步容器 示例(二)HashTable

HashTable示例多线程操作HashTable是线程安全的;import com.example.concurrency.annotations.ThreadSafe;import lombok.extern.slf4j.Slf4j;import java.util.Hashtable;import java.util.Map;imp...

2019-03-29 10:21:00 66

原创 同步容器 示例(一)Vector

同步容器概述同步容器中的方法主要采用synchronized进行同步,这势必会影响性能;同步容器并不一定能做到完全的线程安全;并发容器是可以取代同步容器的;实际变成中,同步容器的使用场景已经越来越少了;同步容器举例ArrayList -> Vector,Stack;HashMap -> HashTable,其key,valu...

2019-03-29 10:16:00 88

原创 线程不安全类 示例(三)先检查再执行

先检查再执行就算a是原子性的,但在if和进入if块之间,别的线程是有可能插进来的;if(condition(a) { handle(a);}

2019-03-29 09:50:00 117

原创 线程不安全类 示例(二)SimpleDateFormat VS joda-time相关类

关于SimpleDateFormatSimpleDateFormat这个类本身是线程不安全的;对于它的使用,要作为局部变量,以堆栈封闭的方式,线程安全的使用 ;关于joda-time相关类这个包中提供的时间相关类是线程安全的,其依赖为:<dependency> <groupId>joda-time</...

2019-03-28 17:34:00 100

原创 线程不安全类 示例(一)StringBuilder VS StringBuffer

线程不安全类如果一个类的对象同时可以被多个线程访问,如果不做特殊的同步和并发处理,那么这个类就很容易表现出线程不安全的现象,比如抛出异常,逻辑处理错误;StringBuilder示例StringBuilder是线程不安全的;StringBuilder虽然线程不安全,但是性能更高,在方法中以局部变量的方式使用,可以做到线程封闭,从而避免了线程不...

2019-03-28 17:14:00 931

原创 线程封闭

线程封闭把对象封装在一个线程里,只有这一个线程能看到这个对象,就算这个对象不是线程安全的,也不会出现线程安全的问题了;实现线程封闭的方法Ad-hoc线程封闭:程序控制实现,最糟糕,忽略;堆栈封闭局部变量,无并发问题,多个线程访问一个方法的时候,局部变量都会在每个线程里拷贝一份到线程的栈中,即局部变量是不会被多个线程共享的;能用局部变量,...

2019-03-28 16:57:00 43

原创 线程封闭示例 将Request中的信息封闭在ThreadLocal中

ThreadLocal工具类线程通过该工具类,将线程私有的数据存入ThreadLocal中;public class RequestHolder { private final static ThreadLocal<Long> requestHolder = new ThreadLocal<>(); /*...

2019-03-28 16:56:00 451

原创 不可变对象

不可变对象有一种对象只要发布了就是安全的,这就是不可变对象,最典型的例子就是String类的对象;不可变对象是解决并发问题的一种思路;不可变对象需要满足的条件对象创建以后其状态就不能修改;对象所有的域都是final类型;对象是正确创建的(在对象创建期间,this引用没有溢出);实现不可变对象的手段将类声明为final;将所有成员...

2019-03-28 15:29:00 60

原创 安全发布对象(一)发布与逸出

对象发布使一个对象能够被当前范围之外的代码使用;对象逸出一种错误的发布 ,当一个对象还没有构造完成时,就使它被其他线程所见;安全发布对象的4种方式在静态初始化函数中初始化一个对象引用;将对象的引用保存到volatile类型域或者AtomicReference对象中;将对象的引用保存到某个正确构造对象的final类型域中;将对象引用...

2019-03-28 11:55:00 106

原创 线程安全性(三) 有序性

有序性概念Java内存模型中,允许编译器和处理器对指令进行重排序,但是重排序过程不会影响到单线程程序的执行,却会影响到多线程并发执行的正确性;有序性的保证方式volatile可以保证一定的有序性;synchronizedLock另外,Java具备一些先天的有序性,即happens-before原则;happens-before原则见《深...

2019-03-28 00:08:00 71

原创 线程安全性(二) 可见性

可见性一个线程对主内存的修改,可以及时的被其他线程观察到;导致共享变量在线程间不可见的原因线程交叉执行;重排序结合线程交叉执行;共享变量更新后的值没有及时在工作内存和主内存之间更新;JVM提供的2种处理可见性的方案synchronizedvolatileJMM关于synchronized的两条规定;线程解锁前,必须把共享变...

2019-03-27 22:05:00 114

原创 线程安全性(一) 原子性比较

AtomicXXX竞争激烈时能维持常态;性能比Lock还要好;缺点是只能操作一个值;基于synchronized的锁适合竞争不激烈的锁;不可中断锁;可读性好;基于Lock接口实现类的锁竞争激烈时能维持常态;可中断锁;多样化同步; ...

2019-03-27 18:38:00 73

原创 线程安全性(一) 原子性 基于锁的实现 - 基于synchronized实现的计数器

基于synchronized实现的计数器用AtomicInteger可以实现对计数器的原子性操作;把计数器的操作放在用synchronized修饰的方法中同样可以实现对计数器的原子性操作;import com.example.concurrency.annotations.ThreadSafe;import lombok.extern.slf4...

2019-03-27 18:25:00 427

原创 线程安全性(一) 原子性 基于锁的实现 - synchronized修饰类

synchronized修饰类和synchronized修饰静态方法是一样的,作用对象都是这个类所有的对象;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;@...

2019-03-27 18:16:00 80

原创 线程安全性(一) 原子性 基于锁的实现 - synchronized修饰静态方法

synchronized修饰静态方法示例synchronized修饰静态方法,其作用对象是这个类的所有对象;2个不同的对象在不同的线程中访问静态方法,按顺序一个一个线程的执行,不会多个线程同时执行;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.ExecutorServ...

2019-03-27 18:07:00 136

原创 线程安全性(一) 原子性 基于锁的实现 - synchronized修饰方法

synchronized修饰方法 - 正例同一个对象在不同线程中访问同步方法,同步方法对这些线程是能起到同步作用的;如果SynchronizedMethod是个父类,那么子类中的test2()是带不上synchronized的;import lombok.extern.slf4j.Slf4j;import java.util.concurr...

2019-03-27 17:22:00 110

原创 线程安全性(一) 原子性 基于锁的实现 - synchronized修饰代码块

锁概述锁是Java中除了AtomicXXX类之外,另一种实现原子性的方式,典型的2中基于锁实现原子性的方式是synchronized关键字和基于Lock接口的实现类;synchronized关键字加锁依赖于JVM的锁实现有synchronized关键字加锁;synchronized关键字加的锁是不可中断锁,适合竞争不激烈,可读性好;synchr...

2019-03-27 16:52:00 227

原创 线程安全性(一) 原子性 AtomicBoolean让代码只执行一次

AtomicBoolean示例通过AtomicBoolean控制,让某段代码只执行一次;import com.example.concurrency.annotations.ThreadSafe;import lombok.extern.slf4j.Slf4j;import java.util.concurrent.CountDownLatc...

2019-03-27 14:24:00 627

空空如也

空空如也

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

TA关注的人

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