线程阻塞

java中锁的概念

北慕城南 提交于 2020-03-25 16:40:28
可重入锁(递归锁) 本文里面讲的是广义上的可重入锁,而不是单指 JAVA 下的 ReentrantLock。可重入锁,也叫做递归锁,指的是 同一线程 外层函数获得锁之后 ,内层递归函数仍然有获取该锁的代码,但不受影响 。在 JAVA 环境下 ReentrantLock 和 synchronized 都是 可重入锁。当然有可重入锁就有不可重入锁,不可重入锁就是 同一线程 外层函数获得锁之后 ,只能当前函数使用 package com.yjc.juc; import java.util.concurrent.locks.ReentrantLock; class ZiYuan { ReentrantLock reentrantLock = new ReentrantLock(); public void method1() { reentrantLock.lock(); try { System.out.println("进入方法1"); System.out.println("准备调用方法2"); method2(); } catch (Exception e) { e.printStackTrace(); } finally { reentrantLock.unlock(); } } public void method2() { reentrantLock.lock(); try

nio--自己总结

纵饮孤独 提交于 2020-03-25 15:42:29
阻塞/非阻塞 + 同步/异步 其实,这两者存在本质的区别,面向的对象是不同的。 阻塞/非阻塞:进程/线程需要操作的数据如果尚未就绪, 是否妨碍了当前进程/线程的后续操作 。 同步/异步:数据如果尚未就绪, 被调用方是否需要拿到数据结果再返回 。 reactor: 通知我有就绪状态了, preactor:通知我数据已经从内核拷贝到了用户空间。 1.同步与异步 同步和异步关注的是 消息通信机制 (synchronous communication/ asynchronous communication) 所谓同步,就是在发出一个*调用*时,在没有得到结果之前,该*调用*就不返回。但是一旦调用返回,就得到返回值了。 换句话说,就是由*调用者*主动等待这个*调用*的结果。 而异步则是相反, *调用*在发出之后 ,这个调用就直接返回了,所以没有返回结果 。换句话说,当一个异步过程调用发出后,调用者不会立刻得到结果。而是在*调用*发出后,*被调用者*通过状态、通知来通知调用者,或通过回调函数处理这个调用。 典型的异步编程模型比如Node.js 举个通俗的例子: 你打电话问书店老板有没有《分布式系统》这本书,如果是同步通信机制,书店老板会说,你稍等,”我查一下",然后开始查啊查,等查好了(可能是5秒,也可能是一天)告诉你结果(返回结果)。 而异步通信机制,书店老板直接告诉你我查一下啊

Python 中的协程 (3) 基础概念

戏子无情 提交于 2020-03-25 15:36:58
1 进程和线程 进程 Process:一个正在运行的应用程序在操作系统中被视为一个进程,进程可以包括一个或多个线程。线程是操作系统分配处理器时间的基本单元,在进程中可以有多个线程同时执行代码。进程之间是相对独立的,一个进程无法访问另一个进程的数据(除非利用分布式计算方式)。 线程 Thread: 线程是进程中的基本执行单元,是操作系统分配CPU时间的基本单位,一个进程可以包含若干个线程,在进程入口执行的第一个线程被视为这个进程的主线程。线程主要是由CPU寄存器、调用栈和线程本地存储器(Thread Local Storage,TLS)组成的。CPU寄存器主要记录当前所执行线程的状态,调用栈主要用于维护线程所调用到的内存与数据,TLS主要用于存放线程的状态信息。线程的本质:线程不是一个计算机硬件的功能,而是操作系统提供的一种逻辑功能,线程本质上是进程中一段并发运行的代码,所以线程需要操作系统投入CPU资源来运行和调度。 进程和线程的区别:进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些

CountDownLatch、CyclicBarrier、Semaphore、Exchanger

自作多情 提交于 2020-03-25 09:19:38
CountDownLatch: 允许N个线程等待其他线程完成执行。无法进行重复使用,只能用一次。 比如有2个任务A,它要等待其他4个任务执行完毕之后才能执行,此时就可以利用CountDownLatch来实现这种功能了。 public class Test { public static void main(String[] args) { final CountDownLatch latch = new CountDownLatch(2); new Thread(){ public void run() { try { System.out.println("子线程"+Thread.currentThread().getName()+"正在执行"); Thread.sleep(3000); System.out.println("子线程"+Thread.currentThread().getName()+"执行完毕"); latch.countDown(); } catch (InterruptedException e) { e.printStackTrace(); } }; }.start(); new Thread(){ public void run() { try { System.out.println("子线程"+Thread.currentThread()

《Python标准库》 目录

末鹿安然 提交于 2020-03-25 05:46:41
目录 译者序 序 前言 第1章 文本 1.1 string—文本常量和模板 1.1.1 函数 1.1.2 模板 1.1.3 高级模板 1.2 textwrap—格式化文本段落 1.2.1 示例数据 1.2.2 填充段落 1.2.3 去除现有缩进 1.2.4 结合dedent和fill 1.2.5 悬挂缩进 1.3 re—正则表达式 1.3.1 查找文本中的模式 1.3.2 编译表达式 1.3.3 多重匹配 1.3.4 模式语法 1.3.5 限制搜索 1.3.6 用组解析匹配 1.3.7 搜索选项 1.3.8 前向或后向 1.3.9 自引用表达式 1.3.10 用模式修改字符串 1.3.11 利用模式拆分 1.4 difflib—比较序列 1.4.1 比较文本体 1.4.2 无用数据 1.4.3 比较任意类型 第2章 数据结构 2.1 collections—容器数据类型 2.1.1 Counter 2.1.2 defaultdict 2.1.3 deque 2.1.4 namedtuple 2.1.5 OrderedDict 2.2 array—固定类型数据序列 2.2.1 初始化 2.2.2 处理数组 2.2.3 数组与文件 2.2.4 候选字节顺序 2.3 heapq—堆排序算法 2.3.1 示例数据 2.3.2 创建堆 2.3.3 访问堆的内容 2.3.4 堆的数据极值 2

线程数,射多少更舒适?

心已入冬 提交于 2020-03-25 02:49:25
3 月,跳不动了?>>> 我相信大家都用过线程池,但是线程池数量设置为多少比较合理呢? 线程数的设置的最主要的目的是为了充分并合理地使用 CPU 和内存等资源,从而最大限度地提高程序的性能,因此让我们一起去探索吧! 首先要考虑到 CPU 核心数,那么在 Java 中如何获取核心线程数? 可以使用 Runtime.getRuntime().availableProcessor() 方法来获取(可能不准确,作为参考) 在确认了核心数后,再去判断是 CPU 密集型任务还是 IO 密集型任务: CPU 密集型任务:比如像加解密,压缩、计算等一系列需要大量耗费 CPU 资源的任务, 大部分场景下都是纯 CPU 计算 。 IO 密集型任务:比如像 MySQL 数据库、文件的读写、网络通信等任务,这类任务 不会特别消耗 CPU 资源,但是 IO 操作比较耗时,会占用比较多时间 。 在知道如何判断任务的类别后,让我们分两个场景进行讨论: CPU 密集型任务 对于 CPU 密集型计算,多线程本质上是提升多核 CPU 的利用率,所以对于一个 8 核的 CPU,每个核一个线程,理论上创建 8 个线程就可以了。 如果设置过多的线程数,实际上并不会起到很好的效果。此时假设我们设置的线程数量是 CPU 核心数的 2 倍,因为计算任务非常重,会占用大量的 CPU 资源,所以这时 CPU

AQS的数据结构及实现原理

可紊 提交于 2020-03-24 23:43:42
  接下来从实现角度来分析同步器是如何完成线程同步的。主要包括:同步队列、独占式同步状态获取与释放、共享式同步状态获取与释放以及超时获取同步状态等。 1、同步队列   同步器依赖内部的一个同步队列来完成同步状态的管理。当线程获取同步状态失败时,会被加入到队列中,并同时阻塞线程。当同步状态释放时,会把首节点中的线程唤醒,使其在册尝试获取同步状态。(疑问: 1、确定只唤醒首节点么,这不就是公平方式获取了么?2、首节点是否能一定获取到锁,为什么? )   a、确定只唤醒了首节点,的确这个获取方式相对比较公平,虽然新节点也可能优先获取到锁。待稍后对比重入锁获取过程;     [对比过后]:重入锁获取逻辑,就是先判断是否有人在用锁,如果有,判断是不是当前线程,如果不是,则当前线程排队,一旦进入排队队列,其实对这个队列来说,真的就是公平锁了,不公平的地方在于后来新来的线程可能会由于首节点刚好释放而获取到锁,造成“插队”;   b、首节点不一定能获取到,因为可能有新线程正好进入,然后获取了锁;   同步队列中的数据类型为Node,其中各个属性描述如下: int waitStatus 等待状态: 1 ,在队列中等待的线程等待超时或者被中断,从队列中取消等待; -1,后继节点处于等待; -2,节点在等待队列中,当condition被signal()后,会从等待队列转到同步队列; -3

Unsafe 相关整理

假装没事ソ 提交于 2020-03-24 18:21:08
1. Unsafe 类 Java 不能直接访问操作系统底层,而是通过本地方法来访问。Unsafe 类提供了硬件级别的原子操作。 Unsafe 类在 sun.misc 包下,不属于 Java 标准。很多 Java 的基础类库,包括一些被广泛使用的高性能开发库都是基于 Unsafe 类开发,比如 Netty、Hadoop、Kafka 等。 Unsafe 是用于在实质上扩展 Java 语言表达能力、便于在更高层(Java 层)代码里实现原本要在更低层(C 层)实现的核心库功能用的。 这些功能包括裸内存的申请/释放/访问,低层硬件的 atomic/volatile 支持,创建未初始化对象等。 它原本的设计就只应该被标准库使用,因此不建议在生产环境中使用。 1.1 获取实例 Unsafe 对象不能直接通过 new Unsafe() 或调用 Unsafe.getUnsafe() 获取。 Unsafe 被设计成单例模式,构造方法私有。 getUnsafe 被设计成只能从引导类加载器(bootstrap class loader)加载。 private Unsafe() { } public static Unsafe getUnsafe() { Class var0 = Reflection.getCallerClass(2); if (var0.getClassLoader() != null

Invoke and BeginInvoke

两盒软妹~` 提交于 2020-03-24 11:48:46
在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate。 一、为什么Control类提供了Invoke和BeginInvoke机制? 关于这个问题的最主要的原因已经是dotnet程序员众所周知的,我在此费点笔墨再次记录到自己的日志,以便日后提醒一下自己。 1、windows程序消息机制 Windows GUI程序是基于消息机制的,有个主线程维护着一个消息泵。这个消息泵让windows程序生生不息。 Windows GUI程序的消息循环 Windows程序有个消息队列,窗体上的所有消息是这个队列里面消息的最主要来源。这里的while循环使用了GetMessage()这个方法,这是个阻塞方法,也就是队列为空时方法就会被阻塞,从而这个while循环停止运动,这避免了一个程序把cpu无缘无故地耗尽,让其它程序难以得到响应。当然在某些需要cpu最大限度运动的程序里面就可以使用另外的方法,例如某些3d游戏或者及时战略游戏中,一般会使用PeekMessage()这个方法,它不会被windows阻塞,从而保证整个游戏的流畅和比较高的帧速。 这个主线程维护着整个窗体以及上面的子控件。当它得到一个消息,就会调用DispatchMessage方法派遣消息,这会引起对窗体上的窗口过程的调用。窗口过程里面当然是程序员提供的窗体数据更新代码和其它代码。 2

Spring Cloud 系列之 Netflix Hystrix 服务容错

情到浓时终转凉″ 提交于 2020-03-24 10:10:24
3 月,跳不动了?>>>    什么是 Hystrix      Hystrix 源自 Netflix 团队于 2011 年开始研发。2012年 Hystrix 不断发展和成熟,Netflix 内部的许多团队都采用了它。如今,每天在 Netflix 上通过 Hystrix 执行数百亿个线程隔离和数千亿个信号量隔离的调用。极大地提高了系统的稳定性。   在分布式环境中,不可避免地会有许多服务依赖项中的某些服务失败而导致 雪崩效应 。Hystrix 是一个库,可通过添加等待时间容限和容错逻辑来帮助您控制这些分布式服务之间的交互。Hystrix 通过隔离服务之间的访问点,停止服务之间的级联故障并提供后备选项来实现此目的,所有这些都可以提高系统的整体稳定性。    雪崩效应      在微服务架构中,一个请求需要调用多个服务是非常常见的。如客户端访问 A 服务,而 A 服务需要调用 B 服务,B 服务需要调用 C 服务,由于网络原因或者自身的原因,如果 B 服务或者 C 服务不能及时响应,A 服务将处于阻塞状态,直到 B 服务 C 服务响应。此时若有大量的请求涌入,容器的线程资源会被消耗完毕,导致服务瘫痪。服务与服务之间的依赖性,故障会传播,造成连锁反应,会对整个微服务系统造成灾难性的严重后果,这就是服务故障的“雪崩”效应。以下图示完美解释了什么是雪崩效应。      当一切服务正常时