Java多线程基础
文章平均质量分 71
以实战的方式介绍Java多线程编程
Iovems
这个作者很懒,什么都没留下…
展开
-
21.JDK提供的并发容器
并发容器概述java.util.concurrent包中的并发容器ConcurrentHashMap高效并发的HashMap。你可以将它理解为线程安全的HashMapCopyOnWriteArrayList在读多写少的场合,这个List的性能非常好,远远好于VectorConcurrentLinkedQueue高效的并发队列,使用链表实现。你可以把它看作是线程安全的LinkedListBlocki...原创 2018-04-09 19:33:36 · 1316 阅读 · 0 评论 -
20.核心线程池的内部实现
核心的几个线程池内部都是使用ThreadPoolExecutor实现的。public static ExecutorService newFixedThreadPool(int nThreads){ return new ThreadPoolExecutor(nThreads, nThreads, ...原创 2018-04-02 10:39:32 · 2790 阅读 · 1 评论 -
19.自定义线程池
自定义线程创建:ThreadFactory//ThreadFactory接口只有一个方法,用来创建线程//当线程池需要新建线程时,就会调用这个方法Thread newThread(Runnable r); 自定义线程池可以让我们,跟踪线程池到底创建可多少线程,也可以自定义线程的名字,组等信息。总之,使用自定义线程池可以让我们更加自由地设置线程池中所有线程的状态。扩展线程池优化线程池...原创 2018-04-03 11:07:39 · 926 阅读 · 0 评论 -
18.JDK线程池概述
什么是线程池 为了避免系统频繁地创建和销毁线程,可以让创建的线程进行复用。线程池中,有几个活跃的线程,当你需要的线程时候,可以从线程池中哪一个空闲线程。使用完毕后,不关闭这个线程,而是把线程还回线程池。 简单来说,在使用线程池后,创建线程变成了从线程池获得空闲线程,关闭线程变成了向线程池归还线程。JDK对线程池的支持 JDK提供了Executor框架,帮助我们...原创 2018-03-31 13:35:11 · 1013 阅读 · 0 评论 -
17.拒绝策略
ThreadPoolExecutor的最后一个参数指定了拒绝策略,也就是当线程池中的线程已经使用完了,无法为新的任务服务,同时等待队列中也已经排满了,再也无法塞下新任务了。拒绝策略就是用来处理这个情况的。 JDK内置了四种拒绝策略: 1.AbortPolicy:直接抛出异常,阻止系统正常工作; 2.CallerRunsPolicy:只要线程池未关闭...原创 2018-04-03 08:42:14 · 1293 阅读 · 0 评论 -
16.线程阻塞工具类:LockSupport
LockSupport可以在线程内任意位置让线程阻塞,和Thread.suspend()相比,它弥补了由于resume()发生在前,导致线程无法继续执行的情况。和Object.wait()相比,它不需要先获得某个对象的锁,也不会抛出InterruptedException异常。 LockSupport的静态方法park()可以阻塞当前线程,类似的还有parkNanos()...原创 2018-04-01 20:13:37 · 1075 阅读 · 0 评论 -
15.循环栅栏:CyclicBarrier
CyclicBarrier与CountDownLatch功能类似,也可以实现线程间的计数等待,但它的功能比CountDownLatch更加强大。 CyclicBarrier之所以翻译为循环栅栏,栅栏的意思就是,阻止线程继续执行,要求线程在栅栏出等待。循环的意思是指,这个栅栏可以反复使用。 比如,我们设置计数器为10,那么凑齐第一批10个线程之后,计数器就会归零...原创 2018-03-30 15:51:11 · 1040 阅读 · 0 评论 -
14.倒计时器:CountDownLatch
CountDownLatch是一个非常实用的多线程控制工具类,它通常用来控制线程等待,可以让某个线程保持等待直到一定数量的线程执行结束,再开始执行。//接收一个整数参数,作为这个倒计时器的计数个数//表示多少个线程执行完毕之后,我才执行public CountDownLatch(int count)public class CountDownLatchDemo implement...原创 2018-03-30 14:32:49 · 1016 阅读 · 0 评论 -
13.JDK并发包-同步控制之信号量(Semaphore)
信号量是对锁的扩展。无论是内部锁synchronized还是重入锁ReentrantLock,一次都只允许一个线程访问某个临界资源。但信号量可以指定多个线程,同时访问某个临界资源。//信号量的构造函数public Semaphore(int permits) //指定信号量的准入数,即同时能申请多少个许可//当一个线程每次只申请一个许可时,这就相当于指定了同时最多有多少个线程可...原创 2018-03-21 16:20:30 · 651 阅读 · 1 评论 -
12.JDK并发包-同步控制之Condition条件
Condition的作用和wait(),notify()方法的作用是大致相同的。但是wait()和notify()方法是个synchronized关键字结合使用的,而Condition是和重入锁结合使用的。重入锁实现了Lock接口。 通过Lock接口的Condition newCondition()方法就可以生成一个与当前重入锁绑定的Condition实例。利用Condit...原创 2018-03-21 15:25:58 · 621 阅读 · 0 评论 -
11.ReadWriteLock读写分离锁
ReadWriteLock读写分离锁可以有效地减少锁竞争,以提升系统性能。 比如线程A1,A2,A3进行写操作,B1,B2,B3进行读操作。如果使用重入锁(ReenTrantLock)或内部锁(Synchronized),则所有的读之间,读与写之间,写与写之间都是串行的。由于读操作并不对数据的完整性造成破坏,所以这种等待其实是不合理的。因此,就有了读写分离锁。 ...原创 2018-03-30 10:12:56 · 1576 阅读 · 1 评论 -
10.J.U.C-同步控制之重入锁(ReentrantLock)
前言 ReeterLock和synchronized具有相同的内存语义; 0.与sysnchronized相比,重入锁具有显示的操作过程,开发人员必须指定何时加锁,何时释放锁。因此,重入锁更加灵活; 1.与synchronized相比,ReentrantLock功能更加强大; 2.ReentrantLock还提供了条件Condition,对线程的...原创 2018-03-21 10:30:25 · 697 阅读 · 0 评论 -
9.J.U.C:AQS(队列同步器)
AQS,AbstractQueuedSynchronizer,即队列同步器; 它是构建锁或者其他同步组件的基础(如ReentrantLock、ReentrantReadWriteLock、Semaphore等),是JUC并发包中的核心基础组件; AQS实现了同步器涉及的大量细节问题,例如获取同步状态、FIFO同步队列等等;所以,基于AQS构建同步器可以极大地减少工作...原创 2018-03-17 15:54:10 · 684 阅读 · 0 评论 -
8.详解:synchronized的使用方法和实现原理
synchronized是内部锁,相对于重入锁ReentrantLock,它是一个比较重量级,比较笨重的锁。 虽然synchronized基于JVM提供了便捷的隐式获取锁释放锁机制,但是它却缺少了获取锁与释放锁的可操作性,可中断、超时获取锁,且它的独占式在高并发场景下性能大打折扣; 使用synchronized有以下几个原则: 1.作为sychron...原创 2018-04-09 20:48:43 · 1558 阅读 · 0 评论 -
7.Java内存模型-volatile的使用方法和实现原理
使用方法 为了在适当的场合,确保线程间的有序性,可见性和原子性,Java使用了一些特殊的操作或者关键字来申明,告诉虚拟机,在这个地方,需要注意不能随意变动或优化目标指令。 关键字volatile就是其中之一。 当你用volatile去申明一个变量时,就等于告诉虚拟机,这个变量极有可能会被某个程序或线程修改。为了确保这个变量被修改后,应用程序范围内的所有线程都能看...原创 2018-03-16 23:00:01 · 444 阅读 · 0 评论 -
6.Java内存模型(JMM)-指令重排
在执行程序时,为了提高性能,处理器和编译器常常会对指令进行重排序;当然不能随意重排序,指令重排需要满足以下两个条件: 1.在单线程环境下不能改变程序运行的结果; 2.存在数据依赖关系的不允许重排序; 其实这两点可以归结于一点:happens-before规定的顺序不能改变,其他的JMM允许任意的排序; 从硬件架构上来说,指令重排序是指CP...原创 2018-04-18 15:27:00 · 1516 阅读 · 0 评论 -
5.Java内存模型(JMM)-happens-before规则
前言 从JDK 5 开始,JMM就使用happens-before的概念来阐述多线程之间的内存可见性; 在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须存在happens-before关系;i = 1; //线程A执行j = i ; //线程B执行 j是否等于1呢?假定线程A的操作(i = 1)happ...原创 2018-04-18 14:31:50 · 1260 阅读 · 0 评论 -
4.Java内存模型(JMM)-概述
缓存一致性问题 计算机在运行程序时,每条指令都是在CPU中执行的,在执行过程中势必会涉及到数据的读写。但数据是存储在主存中,读写主存中的数据没有CPU中执行指令的速度快; 所以,如果任何的交互都需要与主存打交道则会大大影响效率,那就有了CPU高速缓存。每个CPU都有高速缓存,它只与在该CPU上运行的线程有关; 在程序运行中,会将运行所需要的数据复制一份到CPU高...原创 2018-03-16 15:39:33 · 439 阅读 · 0 评论 -
3.线程的基础知识
进程是程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位。在早期面向进程设计的计算机结构中,进程是程序的基本执行实体,在当代面向线程设计的计算机结构中,进程是线程的容器。程序是数据及其组织形式的描述,进程是程序的实体。 简单地说就是,在windows中,看到后缀为.exe的文件,都是一个程序。当你双击这个.exe运行的时候,这个.exe文件中的指令就会...原创 2018-03-16 22:54:14 · 376 阅读 · 0 评论 -
2.Java高并发必须要知道的几个概念(二)
并发级别 由于临界区的存在,多个线程之间的并发必须受到控制。我们把并发的级别分为:阻塞,无饥饿,无障碍,无锁和无等待。阻塞(Blocking) 阻塞的线程在其他线程释放资源之前,无法继续执行。我们使用的synchronized和重入锁,都会在继续执行后续代码之前,尝试获得临界区的锁,如果得不到,该线程就会被挂起(阻塞),直到得到想要的资源。无饥饿(Starvation-Fr...原创 2018-03-16 14:34:27 · 481 阅读 · 0 评论 -
1.Java高并发必须要知道的几个概念(一)
同步(Synchronous)和异步(Asynchronous) 同步和异步通常用来形容一次方法调用。同步方法调用一旦开始,调用者必须等到方法返回后,才能继续后续的行为。异步方法调用更像一个消息传递,一旦开始,方法调用就会立即返回,调用者就可以继续后续的操作。而异步方法通常会在另外一个线程中“真实”地执行。并发(Concurrency)和并行(Parallelism) 并发...原创 2018-03-15 22:55:10 · 520 阅读 · 0 评论