线程

《java并发编程的艺术》二 java并发机制的底层实现原理

帅比萌擦擦* 提交于 2020-02-29 21:53:59
一、volatile的应用 volatile的定义与实现原理 volatile的两条实现原则: (1)Lock前缀指令会引起处理器缓存回写到内存。 (2)一个处理器的缓存回写到内存会导致其他处理器的缓存无效。 如果通过嗅探一个处理器来检测其他处理器打算写内存地址,而这个地址当前处于共享状态,那么正在嗅探的处理器将使它的缓存行无效,在下次访问相同内存地址时,强制执行缓存行填充。 二、synchronized的实现原理与应用 java中的每一个对象都可以作为锁,具体表现为以下3种形式: (1)对于普通同步方法,锁的是当前实例对象。 (2)对于静态同步方法, 锁的是当前类的Class对象。 (3)对于同步方法块,锁的是synchronized括号里配置的对象。 1. java对象头 synchronized用的锁是存在java对象头里的。java对象头里的Mark word里默认存储对象的Hashcode、分代年龄和锁标志位。 在运行期间,Mark word里存储的数据会随着锁标志位的变化而变化。 2. 锁的升级与对比 java中的锁一共有四种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态、重量级锁状态,这几个状态会随着竞争情况逐渐升级,锁可以升级但不能降级,这种策略,目的是为了提高获得锁和释放锁的效率。 2.1 偏向锁 经过研究发现,大多数情况下,锁不仅不存在多线程竞争

RxJava 简易上手指南

ぃ、小莉子 提交于 2020-02-29 21:46:32
RxJava简易上手指南 标签(空格分隔): android rxjava 作者:陈小默 版权声明:禁止商用,转载请注明出处 [toc] 本文章仅作为初学者最快上手实践,不会深入涉及代码原理,有兴趣的朋友可以参阅 扔物线-给Android开发者的RxJava详解 #一、介绍 RxJava通过扩展的观察者模式实现异步操作 Observable:被观察者 Observer:观察者 Subscriber:消息订阅者 其中的关系是观察者(Observer)或者消息订阅者(Subscriber)通过订阅(subscribe)的方式观察被观察者(Observable)的行为 #二、回调方法介绍 ##2.1 观察者对象<span id = "观察者对象"></span> //观察者对象 实现了观察者接口,其中泛型代表了观察者需要的相应对象 Observer<String> observer = new Observer<String>() { @Override public void onCompleted() { //观察任务完成时回调 } @Override public void onError(Throwable e) { //发生错误时回调,并即刻终止事件序列的传递(与onCompleted方法互斥) } @Override public void onNext(String s)

wait() notify() notifyAll()小结

♀尐吖头ヾ 提交于 2020-02-29 21:43:47
1.wait()和notify()是如何工作的? 这两个方法不并在Thread类中,而是在Object类中.这说明任何对象都可以调用这两个方法. 这两个方法的方法签名如下: public final void wait() throws InterruptedException; public final native void notify(); 当一个对象实例调用了wait()方法后,当前线程就会在这个对象上等待.比如,线程A中,调用了OBJECT.wait()方法,那么A线程就暂停了执行,转为等待状态,它会一直等待到其他线程调用了同一对象OBJECT.notify()方法为止.这时,这个OBJECT对象就成为两个线程之间有效的通信手段. 如果一个线程调用了OBJECT.wait(),那么它就会进入到一个线程等待的队列当中.这个等待队列当中,可能会有多个线程,因为系统多个线程都在同时等待某一个对象.当OBJECT.notify()被调用,JVM会从这个等待队列中,随机选择一个线程来唤醒. 要注意:上面的过程并不是公平的,不会因为你的线程优先级高,或者先进入等待队列而被优先选择,是完全随机的. 2.notify()和notifyAll()的区别 除了notify()方法外,Object类还有一个方法是:notifyAll()方法.它和notify()的用法基本一致,但不同的是

Java自学-多线程 死锁

不想你离开。 提交于 2020-02-29 20:21:32
Java 演示多线程死锁 当业务比较复杂,多线程应用里有可能会发生 死锁 步骤 1 : 演示死锁 线程1 首先占有对象1,接着试图占有对象2 线程2 首先占有对象2,接着试图占有对象1 线程1 等待线程2释放对象2 与此同时,线程2等待线程1释放对象1 这样就会。。。一直等待下去 package multiplethread; import charactor.Hero; public class TestThread { public static void main(String[] args) { final Hero ahri = new Hero(); ahri.name = "九尾妖狐"; final Hero annie = new Hero(); annie.name = "安妮"; Thread t1 = new Thread(){ public void run(){ //占有九尾妖狐 synchronized (ahri) { System.out.println("t1 已占有九尾妖狐"); try { //停顿1000毫秒,另一个线程有足够的时间占有安妮 Thread.sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e

一次Mariadb死锁排查过程回顾

懵懂的女人 提交于 2020-02-29 20:03:45
场景 在使用某个平台的时候,有些页面发现长时间,部分数据无法加载成功,开始排查问题。 确定是mariadb的问题的过程 访问了几个页面都是正常的,唯独某几个页面查询实时监控数据时无法加载出来, F12 查看接口发现有几个业务相似的接口长时间不返回数据。 既然整体功能是正常的,只有部分页面出现问题,而且都是实时数据无法显示,怀疑是同一个地方出现问题,于是把接口放在一起发现共同点。 都是 timeout 长时间无响应,而且不是前端资源加载的问题, F12 可以看到一个接口的请求过程,例如下图 查看代码逻辑 ,发现几个接口同时查询过一个表,登陆 mariadb ,发现 SELECT 长时间不返回。怀疑是锁表了。 以下所有示例使用 docker 启动 mysql 演示复现。 我先锁表 lock table test read; lock table test write; 发现是卡住了 mysql> select * from test; mysql> 2013 - Lost connection to MySQL server during query 查看长时间卡住的线程 查询进程(如果您有SUPER权限,您可以看到所有线程。否则,您只能看到您自己的线程) show processlist; 但是此命令只能显示前100条数据,要想看全部的数据,请输入 show full

Android ImageView

瘦欲@ 提交于 2020-02-29 19:48:26
ImageView   ImageView,图像视图,直接继承自View类,它的主要功能是用于显示图片,实际上它不仅仅可以用来显示图片,任何Drawable对象都可以使用ImageView来显示。ImageView可以适用于任何布局中,并且Android为其提供了缩放和着色的一些操作。   ImageView的一些常用属性,并且这些属性都有与之对应的getter、setter方法: android:adjustViewBounds:设置ImageView是否调整自己的边界来保持所显示图片的长宽比。 android:maxHeight:设置ImageView的最大高度。 android:maxWidth:设置ImageView的最大宽度。 android:scaleType:设置所显示的图片如何缩放或移动以适应ImageView的大小。 android:src:设置ImageView所显示的Drawable对象的ID。   对于android:scaleType属性,因为关于图像在ImageView中的显示效果,所以有如下属性值可以选择: matrix:使用matrix方式进行缩放。 fitXY:横向、纵向独立缩放,以适应该ImageView。 fitStart:保持纵横比缩放图片,并且将图片放在ImageView的左上角。 fitCenter:保持纵横比缩放图片

通过JVM日志来进行安全点分析

╄→гoц情女王★ 提交于 2020-02-29 19:38:31
许多事件都可能会导致JVM暂停所有的应用线程。这类暂停又被称为”stop-the-world”(STW)暂停。触发STW暂停最常见的原因就是垃圾回收了( github中的一个例子 ),但不同的JIT活动( 例子 ),偏向锁擦除( 例子 ), 特定的JVMTI操作 ,以及许多场景也可能会导致应用程序暂停。 应用程序线程可以被安全地停止掉的那个时间点,就叫做安全点。这一术语也通常用来指代SWT暂停。 通常来讲GC日志都是打开的。然而,并非所有安全点的信息都能完整地记录下来。想获取到完整的日志,可以使用下列的JVM选项: 1 -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime 从参数名字来看你可能会觉得是与GC相关的,其实不然——打开这些选项能够记录下所有的安全点,而不止是GC暂停的。如果你用上述的选项来运行下这个例子( github源码 ) 你会在标准输出中看到如下信息: 1 2 3 4 Application time: 0.3440086 seconds Total time for which application threads were stopped: 0.0620105 seconds Application time: 0.2100691 seconds Total time

Go 为什么这么“快”

狂风中的少年 提交于 2020-02-29 19:29:11
本文主要从 Go 调度器架构层面上介绍了 G-P-M 模型,通过该模型怎样实现少量内核线程支撑大量 Goroutine 的并发运行。以及通过 NetPoller、sysmon 等帮助 Go 程序减少线程阻塞,充分利用已有的计算资源,从而最大限度提高 Go 程序的运行效率。 本文主要介绍了 Go 程序为了实现极高的并发性能,其内部调度器的实现架构(G-P-M 模型),以及为了最大限度利用计算资源,Go 调度器是如何处理线程阻塞的场景。 怎么让我们的系统更快 随着信息技术的迅速发展,单台服务器处理能力越来越强,迫使编程模式由从前的串行模式升级到并发模型。 并发模型包含 IO 多路复用、多进程以及多线程,这几种模型都各有优劣,现代复杂的高并发架构大多是几种模型协同使用,不同场景应用不同模型,扬长避短,发挥服务器的最大性能。 而多线程,因为其轻量和易用,成为并发编程中使用频率最高的并发模型,包括后衍生的协程等其他子产品,也都基于它。 并发 ≠ 并行 并发 (concurrency) 和 并行 ( parallelism) 是不同的。 在单个 CPU 核上,线程通过时间片或者让出控制权来实现任务切换,达到 "同时" 运行多个任务的目的,这就是所谓的并发。但实际上任何时刻都只有一个任务被执行,其他任务通过某种算法来排队。 多核 CPU 可以让同一进程内的 "多个线程" 做到真正意义上的同时运行

Netty 系列之 Netty 高性能之道

纵然是瞬间 提交于 2020-02-29 19:27:47
1. 背景 1.1. 惊人的性能数据 最近一个圈内朋友通过私信告诉我,通过使用 Netty4 + Thrift 压缩二进制编解码技术,他们实现了 10W TPS(1K 的复杂 POJO 对象)的跨节点远程服务调用。相比于传统基于 Java 序列化 +BIO(同步阻塞 IO)的通信框架,性能提升了 8 倍多。 事实上,我对这个数据并不感到惊讶,根据我 5 年多的 NIO 编程经验,通过选择合适的 NIO 框架,加上高性能的压缩二进制编解码技术,精心的设计 Reactor 线程模型,达到上述性能指标是完全有可能的。 下面我们就一起来看下 Netty 是如何支持 10W TPS 的跨节点远程服务调用的,在正式开始讲解之前,我们先简单介绍下 Netty。 1.2. Netty 基础入门 Netty 是一个高性能、异步事件驱动的 NIO 框架,它提供了对 TCP、UDP 和文件传输的支持,作为一个异步 NIO 框架,Netty 的所有 IO 操作都是异步非阻塞的,通过 Future-Listener 机制,用户可以方便的主动获取或者通过通知机制获得 IO 操作结果。 作为当前最流行的 NIO 框架,Netty 在互联网领域、大数据分布式计算领域、游戏行业、通信行业等获得了广泛的应用,一些业界著名的开源组件也基于 Netty 的 NIO 框架构建。 2. Netty 高性能之道 2.1.

Java基础(九)

给你一囗甜甜゛ 提交于 2020-02-29 18:09:58
一、总述 多线程程序在较低的层次上扩展了多任务的概念:一个程序同时执行多个任务。通常,每一个任务称为一个线程,它是线程控制的简称。可以同时运行一个以上线程的程序称为多线程程序。 多进程与多线程的区别:每个进程拥有自己的一整套变量,而线程则共享数据。 二、中断线程 interrupt方法可以用来请求终止线程。当对一个线程调用interrupt方法时,线程的中断状态将被置位。这是每一个线程都具有的boolean标志。 三、线程状态 线程可以有如下六种状态:(要确定一个线程的当前状态,可调用getState方法) 1、New(新创建):当一个线程处于新创建状态时,程序还没有开始运行线程中的代码。 2、Runnable(可运行):在任何给定时刻,一个可运行的线程可能正在运行也可能没有运行。 3、Blocked(被阻塞):当一个线程试图获取一个内部的对象锁,而该锁被其他线程持有,则该线程进入阻塞状态。当所有其他线程释放该锁,并且线程调度器允许本线程持有它的时候,则该线程将变成非阻塞状态。 4、Waiting(等待):当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态。 5、Timed Waiteing(计时等待):有几个方法有一个超时参数。调用它们导致线程进入计时等待状态。这一状态将一直保持到超时期满或者接收到适当的通知。 6、Terminated(被终止):线程被终止的原因有两个