Java多线程
itcats_cn
学习技术,分享技术
展开
-
Java单例设计模式——饿汉式和懒汉式
Java单例设计模式中分为饿汉式和懒汉式,饿汉式不存在线程安全性问题,但这种方法没有实现lazy loading(懒加载)的效果。而懒汉式存在线程安全性问题,这种方法实现了lazy loading(懒加载)的效果1、饿汉式(不存在线程安全性问题)package cn.itcats.thread.safe.singleton;/** * 单例模式中饿汉模式 * @author fat...原创 2018-07-23 14:18:45 · 640 阅读 · 0 评论 -
Java并发编程之synchronized原理分析和执行流程
在理解synchronized原理之前,先理解什么是内置锁。多线程的锁,其实本质上就是给一块内存空间的访问添加访问权限,因为Java中是没有办法直接对某一块内存进行操作的,又因为Java是面向对象的语言,万物皆对象,所以具体的体现就是某一个对象承担锁的功能,每一个对象都可以是一个锁。内置锁,它是一个互斥锁,即最多只有一个线程能够获得该锁。使用方式就是使用 synchronized 关键字...原创 2018-07-22 18:20:35 · 802 阅读 · 0 评论 -
java 中的锁 -- 偏向锁、轻量级锁、自旋锁、重量级锁
之前做过一个测试,详情见这篇文章《多线程 +1操作的几种实现方式,及效率对比》,当时对这个测试结果很疑惑,反复执行过多次,发现结果是一样的: 1. 单线程下synchronized效率最高(当时感觉它的效率应该是最差才对); 2. AtomicInteger效率最不稳定,不同并发情况下表现不一样:短时间低并发下,效率比synchronized高,有时甚至比LongAdder还高出一点,但是高并...原创 2018-07-22 23:40:47 · 317 阅读 · 0 评论 -
Java并发编程工具类:CountDownLatch、CyclicBarrier、Semaphore
在jdk5中,java提供了一些非常有用的辅助工具类,包括CountDownLatch和CyclicBarrier(两者都可以实现线程之间的通信)、Semaphore(控制方法被线程访问的数量),他们三者都依赖于AQS实现,都是共享锁。今天我们就来学习一下这四个辅助类的用法。1、CountDownLatch CountDownLatch基于AQS实现,它由共享锁实现:只要cou...原创 2018-07-31 12:07:50 · 902 阅读 · 0 评论 -
Java并发之深入Future原理源码分析
JDK内置的Future主要使用到了Callable接口和FutureTask类。Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务。Callable接口可以看作是Runnable接口的补充,Callbale含有泛型,相比Runnable接口的run()方法,call()方法带有返回值,并且可以抛出异常。callab...原创 2018-07-31 22:49:39 · 5098 阅读 · 0 评论 -
Java并发之实现一个可重入锁(使用Lock和AQS实现)
可重入锁指的是如果一个线程已经获得了一个锁,那么它可以多次进入这个锁,当然前提是线程需要先获得这个锁。可重入锁是最常使用的锁,Java的内置锁就是可重入锁,使用synchronized关键字可以启用内置锁机制,比如说一个类有两个synchronized方法A和B,在A方法中调用了B方法,如果锁不是可重入的,那么访问B时需要等待A释放锁,无限期等待。后文就来自己实现一个可重入的锁:实现步...原创 2018-07-28 11:58:36 · 973 阅读 · 0 评论 -
Fork/Join框架及其性能介绍
欢迎使用Markdown编辑器写博客本Markdown编辑器使用StackEdit修改而来,用它写博客,将会带来全新的体验哦:Markdown和扩展Markdown简洁的语法代码块高亮图片链接和图片上传LaTex数学公式           &amp转载 2018-08-01 12:06:48 · 776 阅读 · 0 评论 -
Java同步容器与并发容器
1、Java集合容器分类在Java的集合容器框架中,主要有五大类别:Set、List、Queue、Map、Deque、Map。 其中Set、List、Queue、Map、Deque接口分别继承了Collection,Collection和Map是一个顶层接口。 Set: 1. 不允许重复对象 2. 无序容器(但LinkedHashset : 保证元素添加顺序、TreeSet :...原创 2018-08-01 16:15:38 · 306 阅读 · 0 评论 -
CopyOnWriteArrayList、ConcurrentLinkedQueue源码分析
一、CopyOnWriteArrayListCopyOnWrite思想: CopyOnWrite容器即写时复制的容器。通俗的理解是当往一个容器添加元素的时候,不直接往当前容器添加,而是先将当前容器进行Copy,复制出一个新的容器,然后新的容器里添加元素,添加完元素之后,再将原容器的引用指向新的容器。这样做的好处是可以对CopyOnWrite容器进行并发的读,而不需要加锁,因为当前容器不会添加...原创 2018-08-01 17:03:07 · 301 阅读 · 0 评论 -
Java内存模型之重排序
在执行程序时,为了提供性能,处理器和编译器常常会对指令进行重排序,但是不能随意重排序,不是你想怎么排序就怎么排序,它需要满足以下两个条件: 1. 在单线程环境下不能改变程序运行的结果; 2. 存在数据依赖关系的不允许重排序如果看过LZ上篇博客的就会知道,其实这两点可以归结于一点:无法通过happens-before...转载 2018-08-02 19:27:45 · 226 阅读 · 0 评论 -
Java并发编程之happens-before
happens-before是JMM最核心的概念,理解happens-before是理解JMM的关键。 一.JMM的设计 首先,让我们先分析一下JMM的设计意图。从JMM的设计者的角度,在设计JMM的时候要考虑一下两个关键因素: 1.程序员对内存模型的使用。程序员希望内存模型易于理解、易于编程。程序员希望基于一个强内存模型来编写代码。 2.编译器和处理器对内存模型...转载 2018-08-02 20:36:09 · 192 阅读 · 0 评论 -
Java多线程之守护线程与用户线程
Java中有两种线程,一种是用户线程,另一种是守护线程。 用户线程是指用户自定义创建的线程,主线程停止,用户线程不会停止守护线程当进程不存在或主线程停止,守护线程也会被停止。 使用Thread类中的setDaemon(true)方法设置为守护线程...原创 2018-08-22 15:46:21 · 245 阅读 · 0 评论 -
什么是死锁,简述死锁发生的四个必要条件,如何避免与预防死锁
什么是死锁死锁是指多个进程因竞争资源而造成的一种僵局(互相等待),若无外力作用,这些进程都将无法向前推进。例如,在某一个计算机系统中只有一台打印机和一台输入 设备,进程P1正占用输入设备,同时又提出使用打印机的请求,但此时打印机正被进程P2 所占用,而P2在未释放打印机之前,又提出请求使用正被P1占用着的输入设备。这样两个进程相互无休止地等待下去,均无法继续执行,此时两个进程陷入死锁状态。...转载 2018-08-22 23:35:02 · 738 阅读 · 0 评论 -
Java多线程安全性问题总结
Java多线程存在安全性问题的三个必备条件:处于多线程环境下 多个线程共享一个资源 对资源进行非原子性操作 解决线程安全性问题的方法:使用synchronized关键字(串行执行,同一时刻只有一个线程进入synchronized方法体或同步块),jdk1.6后对synchronized进行优化,引入了——偏向锁、轻量级锁、重量级锁 volatile能保证变量在线程之间的可见性,...原创 2018-07-22 17:34:59 · 1069 阅读 · 0 评论 -
用生活举例看Java多线程活跃性问题【死锁、饥饿、活锁】
死锁:吃饭问题,5个人每人只有一双筷子,只有让另外一个人分享他自己的筷子给自己,自己才能吃到饭。若存在这样的情况,若每个人都不把自己的筷子借给别人用餐,每个人都抓着自己手中的筷子不放,那么每个人都吃不上饭饿死了。也就是说A线程拥有B线程所需的资源,B线程也有A线程所需资源,但两者都不把资源分享出来,最后需求达不到,最后饿死。饥饿问题:学校饭堂排队打饭,但有些人无秩序插队,那么插队的人拥有...原创 2019-04-12 18:07:21 · 777 阅读 · 0 评论 -
Java多线程之volatile的原理和应用
在了解volatile之前需要补充一些知识:我们无法确保执行读操作的线程能适时地看到其他线程写入的值,有时甚至是根本不可能的事情。为了确保多个线程之间对内存写入操作的可见性,必须使用同步机制。在 Java 中 volatile、synchronized 和 final 实现可见性。可见性,是指线程之间的可见性,一个线程修改的状态对另一个线程是可见的。也就是一个线程修改的结果。另一个线程...原创 2018-07-23 17:35:30 · 235 阅读 · 0 评论 -
Java原子类Atomic原理和应用
jdk所提供的原子类可以大致分为四种类型:原子更新基本数据类型 原子更新数组类型 原子更新抽象数据类型 原子更新字段 先来看看jdk提供的原子类(rt.jar包下java.util.concurrent.atomic): 首先我们来写一个数字自增生成器package cn.itcats.thread.safe.Test1;public class Sequen...原创 2018-07-23 22:27:30 · 5776 阅读 · 0 评论 -
Java多线程中Lock接口解析
Lock是java.util.concurrent.locks包下的一个接口主要方法有:Lock接口的实现类Lock相关实现类还可以定义公平锁,如ReentrantLock(boolean) package cn.itcats.thread.safe.Test1;import java.util.concurrent.locks.Lock;import ja...原创 2018-07-23 23:33:21 · 240 阅读 · 0 评论 -
AQS原理与源码分析
AQS介绍AQS,即AbstractQueuedSynchronizer, 队列同步器,它是Java并发用来构建锁和其他同步组件的基础框架。来看下同步组件对AQS的使用:AQS是一个抽象类,主是是以继承的方式使用。AQS本身是没有实现任何同步接口的,它仅仅只是定义了同步状态的获取和释放的方法来供自定义的同步组件的使用。从图中可以看出,在java的同步组件中,AQS的子类(Sync等)一般是...原创 2018-07-28 18:05:55 · 286 阅读 · 0 评论 -
ReentrantReadWriteLock源码与锁升降级详解
//读写锁 private ReadWriteLock lock =new ReentrantReadWriteLock(); //读锁 ————共享锁 private Lock readLock = lock.readLock(); //写锁 ————排它锁 private Lock writeLock =lock.writeLock();Reentran...原创 2018-07-28 23:15:36 · 1348 阅读 · 1 评论 -
wait、notify、notifyAll解析
wait()、notify、notifyAll() 方法无法被重写,因为它们都是Object的本地final方法,每个对象都有锁,锁是每个对象的基础,当然操作锁的方法也是最基础了。 wait()使当前线程阻塞,前提是 必须先获得锁,一般配合synchronized 关键字使用,即,一般在synchronized 同步代码块里使用 wait()、notify/notifyAll(...原创 2018-07-29 17:42:36 · 477 阅读 · 0 评论 -
Java多线程之Condition的使用及源码解析
java中条件变量都实现了java.util.concurrent.locks.Condition接口,条件变量的实例化是通过一个Lock对象上调用newCondition()方法来获取的,这样,条件就和一个锁对象绑定起来了。因此,Java中的条件变量只能和锁配合使用,来控制并发程序访问竞争资源的安全。 条件变量的出现是为了更精细控制线程等待与唤醒,在Java5之前,线程的等待与唤醒依靠的...原创 2018-07-29 23:17:35 · 315 阅读 · 0 评论 -
Java创建多线程的8种方式
目录 Java创建启动线程的多种方式 1、继承Thread类,重写run()方法 2、实现Runnable接口,重写run() 3、匿名内部类的方式 4、带返回值的线程(实现implements Callable<返回值类型>)————以上3种方式,都没有返回值且都无法抛出异...原创 2018-07-21 21:16:51 · 49630 阅读 · 6 评论 -
java Condition源码分析
JUC提供了Lock可以方便的进行锁操作,但是有时候我们也需要对线程进行条件性的阻塞和唤醒,这时我们就需要condition条件变量,它就像是在线程上加了多个开关,可以方便的对持有锁的线程进行阻塞和唤醒。Condition的概念Condition主要是为了在J.U.C框架中提供和Java传统的监视器风格的wait,notify和notifyAll方法类似的功能。JDK的官方解释如下: ...转载 2018-07-30 10:37:29 · 776 阅读 · 0 评论 -
jdbc连接数据库6个步骤及手写实现简易的数据库连接池
我们在学习工作中可能常使用Hibernate、Mybatis、jpa等等框架,这些框架都对数据库连接池有很好的封装,可能忽略了数据库底层的实现,今天我们就一起来看看如何手写一个简易的数据库连接池,在此之前我们先回忆一下java连接数据库的步骤:注册加载jdbc数据库驱动 第一,把驱动程序载入到内存里;第二。把当前载入的驱动程序自己主动去DriverManager那注冊,DriverManag...原创 2018-07-30 13:48:09 · 7625 阅读 · 0 评论 -
Java线程的初始化与中断【结合Thread源码分析】
目录创建一个最简单的线程方法Java线程的初始化Java线程的中断创建一个最简单的线程方法首先,我们知道启动一个新的线程最简单的方法就是:继承Thread类 重写Thread类中的run方法,run()方法内书写具体的执行任务 创建对象调用start()方法具体代码实现如下://代码1package cn.itcats.thread.Test1;publi...原创 2018-07-21 23:00:06 · 697 阅读 · 0 评论 -
【转】Java线程的6种状态及切换
Java中的线程的状态分为6种。1. 初始(NEW):新创建了一个线程对象,但还没有调用start()方法。2. 运行(RUNNABLE):Java线程中将就绪(ready)和运行中(running)两种状态笼统的成为“运行”。线程对象创建后,其他线程(比如main线程)调用了该对象的start()方法。该状态的线程位于可运行线程池中,等待被线程调度选中,获取cpu 的使用权,此时处于就绪...转载 2018-07-22 00:28:26 · 189 阅读 · 0 评论 -
Java多线程之ThreadLocal原理源码分析
什么是ThreadLocal?ThreadLocal 是线程的局部变量, 是每一个线程所单独持有的,其他线程不能对其进行访问, 通常是类中的 private static 字段,是对该字段初始值的一个拷贝,它们希望将状态与某一个线程(例如,用户 ID 或事务 ID)相关联我们知道有时候一个对象的变量会被多个线程所访问,这时就会有线程安全问题,当然我们可以使用synchorinized 关键...原创 2018-07-30 15:23:50 · 283 阅读 · 0 评论 -
Java并发之AQS详解
一、概述 谈到并发,不得不谈ReentrantLock;而谈到ReentrantLock,不得不谈AbstractQueuedSynchronized(AQS)! 类如其名,抽象的队列式的同步器,AQS定义了一套多线程访问共享资源的同步器框架,许多同步类实现都依赖于它,如常用的ReentrantLock/Semaphore/CountDownLatch...。 以下是本文的目录大...转载 2018-07-31 14:18:50 · 282 阅读 · 0 评论