![](https://img-blog.csdnimg.cn/20201014180756913.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
多线程
文章平均质量分 63
IBLiplus
这个作者很懒,什么都没留下…
展开
-
2022年我干啥去了
最近半年干啥去了。。。原创 2022-07-07 15:20:34 · 295 阅读 · 0 评论 -
彻底搞懂Java线程池
ThreadPool1. 为什么存在线程池1.1 降低资源消耗通过复用已存在的线程和降低线程关闭的次数来尽可能降低系统性能损耗;(享元模式)1.2 提升系统响应速度通过复用线程,省去创建线程的过程,因此整体上提升了系统的响应速度;1.3 提高线程的可管理性线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,因此,需要使用线程池来管理线程。至于为什么不允许手动创建线程池,请参见https://dayarch.top/p/why-we-need-to-use-thread原创 2021-08-10 13:27:38 · 1722 阅读 · 0 评论 -
FutureTask源码解析
参考资料(1) future.get方法阻塞问题的解决,实现按照任务完成的先后顺序获取任务的结果(2) Java多线程引发的性能问题以及调优策略(3) 可取消的异步任务——FutureTask用法及解析(4) FutureTask源码解读Future方法介绍public interface Future<V> { // 取消任务 可中断的方式取消 boolean cancel(boolean mayInterruptIfRunning);原创 2020-09-17 17:37:06 · 450 阅读 · 0 评论 -
synchronized的实现原理
在多线程并发编程中synchronized一直是一个元老级的角色,我们先看一下利用synchronized实现同步的基础,Java中每一个对象都可以作为一个锁。 具体表现为3种形式:对于普通同步方法,锁是当前实例对象。 对于静态同步方法,锁的是当前类的Class对象 对于同步方法块,锁是Synchonized括号里配置的对象当一个线程试图访问同步代码块时,它首先必须得到锁,退出或抛出异常...原创 2018-11-04 20:45:37 · 132 阅读 · 0 评论 -
原子操作的实现原理
原子(atomic)本意是“不能被进一步分割的最小粒子”,而原子操作(atomic operation)意为 “ 不可被终端的一个或一系列的操作”。在多处理器实现原子操作就变得有点复杂了。在了解原子操作的实现之前,我们先看一下相关的术语,处理器如何实现原子操作32位IA-32处理器使用基于对缓存加锁或总线加锁的方式来实现多处理器之间的原子操作。首先处理器会自动保证基本的内存操作的原...原创 2018-11-04 22:03:35 · 619 阅读 · 0 评论 -
Java内存模型之从源代码到指令序列的重排序
在执行程序时,为了提高性能,编译器和处理器常常会对指令进行重排序,重排序分3种类型。编译器优化的重排序。编译器在不改变单线程程序予以的前提下,可以重新安排语句的执行顺序。 指令级并行的重排序。现在处理器采用了指令级并行技术来将多条指令重叠执行。如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。 内存系统的重排序。由于处理器使用缓存和读/写缓冲区,这使得加载和存储操作看上去可能...原创 2018-11-04 22:32:12 · 248 阅读 · 0 评论 -
多线程之重排序详解
重排序重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。数据依赖性如果两个操作访问同一个变量,且这两个操作中有一个为写操作,此时这两个操作之间就存在数据的依赖性。数据依赖分为3中类型,如下表所示:上面3中情况,只要重排序两个操作的顺序。程序的结果就会改变。编译器和处理器是可以对操作进行重排序的,在重排序时,会遵守数据依赖性,编译器和处理器不会改变存在数...原创 2018-11-07 14:17:56 · 2061 阅读 · 2 评论 -
Java内存模型之顺序一致性
顺序一致性内存模型是一个理论上的参考模型,在设计的时候,处理器的内存模型和编程语言的内存模型都会以顺序一致性内存模型作为参考。数据竞争与顺序一致性当程序为正确同步时,就可能会存在数据竞争。Java内存模型规范对数据竞争的定义如下:在一个线程中写一个变量 ,在另一个线程中读同一个变量 , 而且写和读没有通过同步来排序。当代码中存在数据竞争时,程序的执行往往产生违反直觉的结果,这个我们...原创 2018-11-07 16:22:40 · 238 阅读 · 0 评论 -
volatile的内存语义
理解volatile特性的一个好方法是把volatile变量的单个读/写.看成是使用同一个锁对这些单个读/写操作做出了同步。其实,volatile的读写操作与锁的获取与释放有这对应的关系,我们来慢慢细看,首先看一下volatile的特性:volatile的特性class VolatileFeaturesExample{ volatile long v1 = 0l; public ...原创 2018-11-07 17:29:55 · 257 阅读 · 0 评论 -
CAS实现原子操作的三大问题
在Java并发包中有一些并发框架也使用了自旋CAS的方式来实现原子性,比如LinkTransferQueue类的Xfer方法。CAS虽然很高效 的解决了原子操作,但是CAS仍然存在三大问题:ABA问题,循环时间开销大,以及只能保证一个共享变量的原子操作。(1)ABA问题因为CAS需要在操作值的时候,检查值有么有发生变化,如没有发生变化则更新,但是如果原来的一个值是A,变成了B,又变成了A,...原创 2018-11-05 09:45:40 · 965 阅读 · 3 评论 -
Java内存模型的抽象结构
在Java中,所有实例域,静态域和数组元素都存储在堆内存中,堆内存在线程之间完成共享。局部变量,方法定义参数和异常处理参数不会在线程之间共享,他们不会有内存可见性问题,也不会受内存模型的影响。Java线程之间的通信有Java内存模型(JMM)控制,JMM决定一个线程对共享变量的写入何时对另外一个线程可见,从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储了该线程以...原创 2018-11-05 10:43:28 · 600 阅读 · 0 评论 -
并发编程模型详解
现在的处理器使用写缓冲区临时保存向内存写入数据。写缓冲区可以保证指令流水线持续运行,他可以避免与处理器停顿下来等待向内存写入数据而产生的延迟。同时,通过一批处理的方式刷新写缓冲区,以及合并写缓冲区中对同一个内存地址的多次写,减少对内存总线的占用。虽然写缓冲区有这么多好处,但是每个处理器上的写缓冲区,仅仅对它所在的处理器可见。这个特性会对内存操作的执行顺序产生重要的影响:处理器对内存的...原创 2018-11-05 14:30:08 · 160 阅读 · 0 评论 -
Java多线程之happen-before简介
在JDK5 开始,Java使用新的JSR-133内存模型,该模型使用happens-before的概念来阐述操作之间的内存可见性。在JMM中,如果一个操作执行的结果需要对另一个操作可见,那么这两个操作之间必须要存在happens-before关系。这里提到的两个操作既可以是一个线程之内,也可以是在不同的线程之间。与我们程序员密切相关的happens-before规则如下。程序顺序规则:一个...原创 2018-11-05 15:17:47 · 524 阅读 · 0 评论 -
synchronized同步
所谓“非线程安全”其实会发生在多个线程对同一个对象中的实例变量进行并发访问时发生,产生的结果就是“脏读”,也就是取到的数据其实时被哼该过的,而“线程安全”就是获得的实体变量的值时经过同步处理的,不会出现脏读的现象。方法内的变量为线程安全方法内的变量为线程安全,“非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程安全问题”。public class Has...原创 2018-12-04 16:40:49 · 182 阅读 · 0 评论 -
Java并发包之CountDownLatch
今天主要来看一下JUC中的CountDownLatch:public class CountDownLatchTest implements Runnable{ static final CountDownLatch countDownLatch = new CountDownLatch(10); static final CountDownLatchTest t = ne...转载 2019-04-03 15:09:22 · 289 阅读 · 0 评论 -
volatile的使用优化
在JDK 7 的并发包中有一个队列集合类Linked-TransferQueue,它在使用volatile变量的时候,用一种追加字节的方式来优化队列出队和入队的性能。追加字节真的能提高性能吗?这种方式看起来很神奇,但如果深入理解处理器架构就能理解其中的奥秘。让我们先看看LinkedTeansferQueue这个类,它使用一个内部类类型来定义队列的头结点和尾节点,而这个内部类相对于父类只做了...原创 2018-11-04 18:37:51 · 424 阅读 · 0 评论 -
Java并发机制的底层实现原理之volatile
Java代码在编译之后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转换为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和CPU的指令。首先看一下volatile的定义:在多线程并发编程中synchronized和volatile都扮演着重要的角色,volatile是轻量级的synchronized,它在处理器开发中保证了共享边浪的“...原创 2018-11-04 17:43:01 · 180 阅读 · 0 评论 -
并发编程要考虑的几点
并发编程的目的是为了让程序运行的更快,但是,并不是启动更多的线程就能让程序最大限度的并发执行。在进行并发编程时,如果希望通过多线程执行任务让程序运行的更快,会面临很多的问题,比如,上下文切换,死锁的问题,以及受限于硬件和软件的资源限制的问题。1.1上下文切换即使是单线程处理器也支持多线程执行代码,CPU通过给每个线程分配CPU时间片来实现这个机制。时间片是CPU分配给各个线程的时间,因为时...原创 2018-10-31 21:23:01 · 512 阅读 · 0 评论 -
Java线程的生命周期
Java多线程编程Java给多线程提供了内置的支持。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发存在多个线程,每条线程并行执行不同的任务。多线程是多任务的一种特别形式。进程:一个进程包括有操作系统分配的内存空间,包含至少一个线程。一个线程不可能单独的存在,它必须是进程的一部分。一个进程会一直不断的进行,直到所有的非守护线程全部执行完毕之后,再能结束进程。线程是一个动态执...原创 2018-10-04 13:50:15 · 253 阅读 · 1 评论 -
Java创建线程的三种方式
在Java中提供了3种创建线程的方法:1、通过实现Runnable接口2、通过继承Thread类本身3、通过Callable或者Future创建线程实现Runnable接口创建线程类 1、定义Runnable接口的实现类,重写run()方法2、创建Runnable实现类的实例,并以此作为Thread的target来创建对象,该对象才是真正的线程对象。package d...原创 2018-10-04 14:44:44 · 170 阅读 · 0 评论 -
Java中的ThreadPooLExecutor类
java.uitl.concurrent.ThreadPoolExecutor类是线程池中最核心的一个类,因此如果要透彻地了解Java中的线程池,必须先了解这个类。下面我们来看一下ThreadPoolExecutor类的具体实现源码。在ThreadPoolExecutor类中提供了四个构造方法:public class ThreadPoolExecutor extends Abstrac...原创 2018-10-04 20:17:55 · 183 阅读 · 0 评论 -
使用ThreadPoolExecutor类创建线程池
一、采用这种方式的优点:可以实时获取线程池内线程的各种状态 可以动态调整线程池大小二、线程池的工作原理简介:如果当前线程池中的线程数目小于corePoolSize,则每来一个任务,就会创建一个线程去执行这个任务; 如果当前线程池中的线程数目>=corePoolSize,则每来一个任务,会尝试将其添加到任务缓存队列当中,若添加成功,则该任务会等待空闲线程将其取出去执行;若添加失败...原创 2018-10-04 20:24:11 · 242 阅读 · 0 评论 -
深入剖析线程池实现原理
1.线程池状态 在ThreadPoolExecutor中定义了一个volatile变量,另外定义了几个static final变量表示线程池的各个状态:volatile int runState;static final int RUNNING = 0;static final int SHUTDOWN = 1;static final int STOP ...原创 2018-10-04 20:38:05 · 206 阅读 · 0 评论 -
如何合理配置线程池的大小
一般需要根据任务的类型来配置线程池大小: 如果是CPU密集型任务,就需要尽量压榨CPU,参考值可以设为 NCPU+1 如果是IO密集型任务,参考值可以设置为2*NCPU 当然,这只是一个参考值,具体的设置还需要根据实际情况进行调整,比如可以先将线程池大小设置为参考值,再观察任务运行情况和系统负载、资源利用率来进行适当调整。 参考:https://blog.csdn.n...原创 2018-10-04 20:42:37 · 615 阅读 · 0 评论 -
Java虚拟机--对象的创建
下面简单说一下Java虚拟机中对象常见的原理:我们编写代码肯定已经是很熟悉了,通过new关键字,给对象实例化并分配内存,但是实际上对象的创建是一步步很复杂的过程,我们先看一下对象创建的流程图。在对象创建之前先要实现Java类的加载。虚拟机类加载机制我们之后会有详细讲解,这里就不详细展开了,而是将重点放在对象的创建方面。我们看一下内存分配对象的几种方式指针碰撞我们首先假设堆内...原创 2018-10-04 21:46:13 · 183 阅读 · 0 评论 -
Java代码实现简单工厂模式
模式定义简单工厂模式(Simple Factory Pattern):又称为静态工厂方法(Static Factory Method)模式,它属于类创建型模式。在简单工厂模式中,可以根据参数的不同返回不同类的实例。简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。模式结构简单工厂模式包含如下角色:Factory:工厂角色Product:抽象产品角色C...原创 2018-10-05 22:01:32 · 4767 阅读 · 0 评论 -
Java多线程之售票问题
三个售票窗口同时出售20张票程序分析:1.票数要使用同一个静态值2.为保证不会出现卖出同一个票数,要java多线程同步锁。设计思路:1.创建一个站台类Station,继承Thread,重写run方法,在run方法里面执行售票操作!售票要使用同步锁:即有一个站台卖这张票时,其他站台要等这张票卖完!2.创建主方法调用类 创建一个站台类,继承Threadpackage se...原创 2018-10-06 17:29:39 · 4255 阅读 · 0 评论 -
synchronized 同步锁(Java)
引言在多线程应用场景中,同步锁是一种非常重要的机制,例如:ID号的分配,多个客户端分别与服务端建立连接,客户端并发请求的情况下,为提升吞吐量,服务端一般采用多线程处理请求,若无同步锁机制,不同线程分配到相同ID号的情况将不可避免,而这种情况与预期相违背。在现实中是有许许多多的例子的,比较典型的有购票,抽奖等。java 同步锁机制介绍java同步锁的关键字为:synchronized,...原创 2018-10-06 20:45:44 · 2938 阅读 · 0 评论 -
synchronized关键字(同步锁)详细解析
这里大部分的解释都在代码中。demo1package synchornizeds;public class Demo1 { private int count; private Object o = new Object(); public void m() { synchronized (o) { //任何线程执行一下代码都要申请o对应的锁。此处的o是堆内存中new...原创 2018-10-08 16:01:47 · 1871 阅读 · 0 评论 -
线程异常释放锁
package synchornizeds;import java.util.concurrent.TimeUnit;import jishuqisuanfa.Main;/* * * 程序在执行过程中,如果出现异常,默认情况锁会被释放 * 所以在并发处理的过程中,有异常要多加小心,不然可能会发生不一致的情况 * 比如,在一个web app处理的过程中,有多个servlet线...原创 2018-10-08 17:01:37 · 933 阅读 · 0 评论 -
volatile关键字讲解(Java)
package synchornizeds;import java.util.concurrent.TimeUnit;/* * volatile 关键字 是一个变量在多个线程间可见 * * A B线程都用到一个变量,Java默认是A线程中保留一份copy,这样如果B线程修改了该变量,则A线程未必会知道 * * 使用volatile关键字 会让所有的线程都会读到变量的...原创 2018-10-08 17:41:07 · 137 阅读 · 0 评论 -
Java线程池
为什么要使用线程池1、创建/销毁线程伴随着系统开销,过于频繁的创建/销毁线程,会很大程度上影响处理效率记创建线程消耗时间T1,执行任务消耗时间T2,销毁线程消耗时间T3如果T1+T3>T2,那么是不是说开启一个线程来执行这个任务太不划算了!正好,线程池缓存线程,可用已有的闲置线程来执行新任务,避免了T1+T3带来的系统开销2、线程并发数量过多,抢占系统资源从而导致阻塞...原创 2018-09-12 19:56:31 · 104 阅读 · 0 评论