【java多线程并发】
文章平均质量分 92
天青色的烟雨.
本博客只为加深自身知识体系,不为任何商业用途呦呦呦!
展开
-
守护线程与非守护线程
Java中有两类线程:User Thread(用户线程)、Daemon Thread(守护线程)用户线程即运行在前台的线程,而守护线程是运行在后台的线程。 守护线程作用是为其他前台线程的运行提供便利服务,而且仅在普通、非守护线程仍然运行时才需要,比如垃圾回收线程就是一个守护线程。当VM检测仅剩一个守护线程,而用户线程都已经退出运行时,VM就会退出,因为没有如果没有了被守护这,也就没有继续运行程...转载 2019-03-24 20:49:36 · 397 阅读 · 0 评论 -
Callable接口、Runable接口、FutureTask接口
1、Callable与Runable区别 Java从发布的第一个版本开始就可以很方便地编写多线程的应用程序,并在设计中引入异步处理。Thread类、Runnable接口和Java内存管理模型使得多线程编程简单直接。 但Thread类和Runnable接口都不允许声明检查型异常,也不能定义返回值。没有返回值这点稍微有点麻烦。不能声明抛出检查型异常则更麻烦一些。...转载 2019-03-31 10:57:24 · 324 阅读 · 0 评论 -
synchronized的底层实现原理(偏向锁、轻量级锁、重入)
理解Java对象头与Monitor在JVM中,对象在内存中的布局分为三块区域:对象头、实例数据和对齐填充。如下: 实例变量:存放类的属性数据信息,包括父类的属性信息,如果是数组的实例部分还包括数组的长度,这部分内存按4字节对齐。 填充数据:由于虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐,这点了解即可。 而对于顶部,则是Jav...转载 2019-03-27 11:34:08 · 3539 阅读 · 1 评论 -
Condition接口、LockSupport工具类
Condition介绍 任意一个Java对象,都拥有一组监视器方法(定义在java.lang.Object中),主要包括wait()、wait(long timeout)、notify()以及notifyAll()方法,这些方法与synchronized同步关键字配合,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通...转载 2019-04-01 11:20:10 · 182 阅读 · 0 评论 -
synchronized和Lock
我们已经知道,synchronized 是java的关键字,是Java的内置特性,在JVM层面实现了对临界资源的同步互斥访问,但 synchronized 粒度有些大,在处理实际问题时存在诸多局限性,比如响应中断等。Lock 提供了比 synchronized更广泛的锁操作,它能以更优雅的方式处理线程同步问题。本文以synchronized与Lock的对比为切入点,对Java中的Lock框...原创 2019-03-28 09:38:56 · 391 阅读 · 0 评论 -
可重入锁ReentrantLock
一、显式锁简介 显式锁,这个叫法是相对于隐式锁synchronized而言的,加锁和解锁都要用户显式地控制。显示锁Lock是在Java5中添加到jdk的,同synchronized一样,这也是一种协调共享对象访问的机制。但是它不是用来替代内置锁的,而是一种可选择的高级功能。1、Lock接口提供了synchronized关键字不具备的主要特性:尝试非阻塞获取锁:当前线程尝试获取锁,如...转载 2019-03-28 10:20:13 · 301 阅读 · 0 评论 -
读写锁ReadWriteLock
隐式锁Synchronized、重入锁ReetrantLock都是互斥锁、独占锁,即同一个锁只能每时每刻至多由一个线程来获持有。互斥,是一种保守策略,虽然避免了“写/写”、“读/写”冲突,但也阻止了安全的“读/读”发生。然而,在不少情况下,数据结构上的操作都是“读操作”,如果此时能放宽加锁需求,允许多个读线程同时访问数据结构,那么将极大地提升程序的性能;而这种能支持共享的锁便被设计出...转载 2019-03-28 11:31:27 · 344 阅读 · 0 评论 -
CAS原子操作、原子操作类
1、乐观锁与悲观锁 我们都知道,cpu是时分复用的,也就是把cpu的时间片,分配给不同的thread/process轮流执行,时间片与时间片之间,需要进行cpu切换,也就是会发生进程的切换。切换涉及到清空寄存器,缓存数据。然后重新加载新的thread所需数据。当一个线程被挂起时,加入到阻塞队列,在一定的时间或条件下,在通过notify(),notifyAll()唤醒回来。 在某个资...原创 2019-03-28 20:09:22 · 407 阅读 · 0 评论 -
AQS深度解析
1、引言 在JDK1.5之前,一般是靠synchronized关键字来实现线程对共享变量的互斥访问。synchronized是在字节码上加指令,依赖于底层操作系统的Mutex Lock实现。 而从JDK1.5以后java界的一位大神—— Doug Lea 开发了AbstractQueuedSynchronizer(AQS)组件,使用原生java代码实现了sync...转载 2019-03-28 21:07:43 · 1023 阅读 · 2 评论 -
AQS注释源码
注释的AQS的源码:如下:public class AbstractQueuedSynchronizerTest { static final class Node { /** Marker to indicate a node is waiting in shared mode */ static final Node SHARED = new N...原创 2019-03-28 21:10:29 · 231 阅读 · 0 评论 -
线程池详解
前言:在实际使用中,线程是很占用系统资源的,如果对线程管理不善很容易导致系统问题。因此,在大多数并发框架中都会使用线程池来管理线程,使用线程池管理线程主要有如下好处:降低资源消耗。通过复用已存在的线程和降低线程关闭的次数来尽可能降低系统性能损耗; 提升系统响应速度。通过复用线程,省去创建线程的过程,因此整体上提升了系统的响应速度; 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,...转载 2019-04-08 15:34:42 · 233 阅读 · 0 评论 -
多线程上下文切换的影响
来自方腾飞老师《Java并发编程的艺术》第一章什么是上下文切换 即使是单核CPU也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时间片非常短,所以CPU通过不停地切换线程执行,让我们感觉多个线程时同时执行的,时间片一般是几十毫秒(ms)。 CPU通过时间片分配算法来循环执行任务,当前任务执行一个时...原创 2019-05-07 10:07:31 · 1154 阅读 · 0 评论 -
死锁的四个必要条件和解决办法
死锁概念及产生原理 概念:多个并发进程因争夺系统资源而产生相互等待的现象。 原理:当一组进程中的每个进程都在等待某个事件发生,而只有这组进程中的其他进程才能触发该事件,这就称这组进程发生了死锁。 本质原因:系统资源有限。 进程推进顺序不合理。死锁产生的4个必要条件互斥:某种资源一次只允许一个进程访问,即该资源一旦分配给某个进程,其他进程就不能再访问,直到该进程...转载 2019-05-07 11:36:22 · 286 阅读 · 0 评论 -
wait方法
一.概念、原理、区别 Java中的多线程是一种抢占式的机制而不是分时机制。线程主要有以下几种状态:可运行,运行,阻塞,等待,等待超时,死亡。抢占式机制指的是有多个线程处于可运行状态,但是只有一个线程在运行。当有多个线程访问共享数据的时候,就需要对线程进行同步。线程中的几个主要方法的比较:Thread类的方法:sleep(),yield()等 Object的方法:wait...转载 2019-03-24 10:33:14 · 5459 阅读 · 0 评论 -
interrupt方法
转载:https://blog.csdn.net/qq_33797928/article/details/794502081、interrupt方法 使用interrupt()中断线程 当一个线程运行时,另一个线程可以调用对应的Thread对象的interrupt()方法来中断它,该方法只是在目标线程中设置一个标志,表示它已经被中断,并立即返回。这里需要注意的是...转载 2019-03-24 09:55:14 · 717 阅读 · 0 评论 -
java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
wait(),notify(),notifyAll() 在Java中,所有对象都能够被作为"监视器monitor"——指一个拥有一个独占锁,一个入口队列和一个等待队列的实体entity。所有对象的非同步方法都能够在任意时刻被任意线程调用,此时不需要考虑加锁的问题。而对于对象的同步方法来说,在任意时刻有且仅有一个拥有该对象独占锁的线程能够调用它们。例如,一个同步方法是独占的。...转载 2019-03-25 10:26:30 · 719 阅读 · 0 评论 -
线程结束方法
线程属于一次性消耗品,在执行完run()方法之后线程便会正常结束了,线程结束后便会销毁,不能再次start,只能重新建立新的线程对象,但有时run()方法是永远不会结束的。例如在程序中使用线程进行Socket监听请求,或是其他的需要循环处理的任务。在这种情况下,一般是将这些任务放在一个循环中,如while循环。当需要结束线程时,如何退出线程呢?有三种方法可以结束线程: 1.设置退出标志,...转载 2019-03-25 10:50:55 · 417 阅读 · 0 评论 -
synchronized应用方式
线程安全是并发编程中的重要关注点,应该注意到的是,造成线程安全问题的主要诱因有两点,一是存在共享数据(也称临界资源),二是存在多条线程共同操作共享数据。因此为了解决这个问题,我们可能需要这样一个方案,当存在多个线程操作共享数据时,需要保证同一时刻有且只有一个线程在操作共享数据,其他线程必须等到该线程处理完数据后再进行,这种方式有个高尚的名称叫互斥锁,即能达到互斥访问目的的锁,也就是...转载 2019-03-25 11:30:35 · 213 阅读 · 1 评论 -
线程的四种创建方式
Java多线程实现方式主要有四种:继承Thread类; 实现Runnable接口; 实现Callable接口通过FutureTask包装器来创建Thread线程; 使用ExecutorService、Callable、Future实现有返回结果的多线程。其中前两种方式线程执行完后都没有返回值,后两种是带返回值的。 在详细了解这四种方法之前,先来理解一下为什么线程要这样...原创 2019-03-25 18:07:53 · 208 阅读 · 0 评论 -
CPU多级缓存与缓存一致性
1、为什么需要CPU缓存我们选购电脑时,CPU处理器的配置会有缓存大小,它是CPU性能的重要指标。为什么呢?因为CPU计算速度远大于访问主存速度,造成cpu资源浪费!我们应该都知道,计算机在执行程序的时候,每条指令都是在CPU中执行的,而执行的时候,又免不了要和数据打交道。而计算机上面的数据,是存放在主存当中的,也就是计算机的物理内存啦。刚开始,还相安无事的,但是随着CP...原创 2019-03-26 11:32:31 · 466 阅读 · 0 评论 -
Java内存模型(JMM)
什么是Java内存模型(抽象的) 我们知道,Java程序是需要运行在Java虚拟机上面的,Java内存模型(Java Memory Model ,JMM)就是一种符合内存模型规范的,屏蔽了各种硬件和操作系统的访问差异的,保证了Java程序在各种平台下对内存的访问都能保证效果一致的机制及规范。 java内存模型的主要目标是定义程序中各个变量的访问规则。此处变量与jav...原创 2019-03-26 12:21:37 · 210 阅读 · 0 评论 -
ThreadLocal底层原理
先总述,后分析 深挖过threadLocal之后,一句话概括:Synchronized用于线程间的数据共享,而ThreadLocal则用于线程间的数据隔离。所以ThreadLocal的应用场合,最适合的是按线程多实例(每个线程对应一个实例)的对象的访问,并且这个对象很多地方都要用到。 数据隔离的秘诀其实是这样的,Thread有个TheadLocalMap类型的属性,叫...原创 2019-03-30 12:01:59 · 725 阅读 · 0 评论 -
Java中Runnable和Thread的区别
Thread和Runnable的区别如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。main函数,实例化线程对象也有所不同,extends Thread :t.start(); implements Runnable : new Thread(t).start();总结:实现implements Runnable接口比...原创 2019-03-23 21:00:00 · 328 阅读 · 0 评论 -
Fork/Join框架介绍
1、Fork/Join框架是什么 Fork/Join框架是一个比较特殊的线程池框架,专用于需要将一个任务不断分解成多个子任务(分支),并将多个子任务的结果不断进行汇总得到最终结果(聚合)的并行计算框架。2、工作窃取算法 工作窃取(work-stealing)算法是指某个线程从其他队列里窃取任务来执行。工作窃取的运行流程图如下: ...转载 2019-03-30 20:18:08 · 277 阅读 · 0 评论 -
重排序、happens-before
指令重排CPU执行单元的速度要远超主存访问速度。在执行程序时,为了提高性能,编译器和处理器会对指令做重排序。编译器优化重排序:编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。 指令级并行的重排序:如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。 内存系统的重排序:处理器使用缓存和读写缓冲区,这使得加载和存储操作看上去可能是在乱序执行。...原创 2019-03-26 22:07:21 · 256 阅读 · 0 评论 -
Volatile关键字详解
基本概念可见性: 可见性是一种复杂的属性,因为可见性中的错误总是会违背我们的直觉。通常,我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情。为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制。 可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是一个线程修改的结果。另一个线程马上就能看到。比如:用volatile修...原创 2019-03-26 22:20:26 · 127 阅读 · 0 评论 -
Java并发工具类--CountDownLatch、CyclicBarrier、Semaphore和Exchange
一、CountDownLatch用法 CountDownLatch是Java1.5之后引入的Java并发工具类,放在java.util.concurrent包下面http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/package-summary.html官方API。 CountDownLatch能够使...转载 2019-03-30 22:06:59 · 552 阅读 · 0 评论 -
Thread中常用API
线程状态线程从创建到最终的消亡,要经历若干个状态。一般来说,线程包括以下这几个状态:创建(new)、就绪(runnable)、运行(running)、阻塞(blocked)、消亡(dead)。当需要新起一个线程来执行某个子任务时,就创建了一个线程。但是线程创建之后,不会立即进入就绪状态,因为线程的运行需要一些条件(比如内存资源,在前面的JVM内存区域划分一篇博文中知道程序计数器、Java栈...原创 2019-03-23 22:17:56 · 293 阅读 · 0 评论 -
线程安全
怎么才能做到类的线程安全?1、栈封闭所有的变量都是在方法内部声明的,这些变量都处于栈封闭状态。2、无状态有状态对象(Stateful Bean) :就是有实例变量的对象,可以保存数据,是非线程安全的。每个用户有自己特有的一个实例,在用户的生存期内,bean保持了用户的信息,即“有状态”;一旦用户灭亡(调用结束或实例结束),bean的生命期也告结束。即每个用户最初都会得到一个初始的b...原创 2019-05-10 17:24:16 · 152 阅读 · 0 评论