![](https://img-blog.csdnimg.cn/20201014180756757.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
java并发编程
云原生手记
欢迎大家关注我的公众号“云原生手记”,将定期更新云计算技术文章
展开
-
《java并发编程实战》——线程安全性
要编写线程安全的代码,其核心在于要对状态访问操作进行管理,特别是对共享的(Shared)和可变的(Mutable)状态的访问。从非正式的意义上说(为啥这么讲我也不知道,可能这么说读者更容易理解),对象的状态是指存储在状态变量(例如实例或者静态域)中的数据。对象的状态可能包括其他依赖对象的域(意思是对象中嵌套使用了其他对象,例如HashMap中有Map.Entry一样)。 “共享”意味...原创 2018-07-08 11:36:15 · 168 阅读 · 0 评论 -
java volatile变量及其使用场景
java中的一种稍弱的同步机制,就是volatile变量,用于确保将变量的更新操作通知到其他线程。变量声明为volatile后:(1)编译器与运行时都会注意到这个变量是共享的,因此不会将该变量上的操作与其他内存操作一起重排序(重排序不懂的,可以自行百度,需要理解)。(2)volatile变量不会被缓存在寄存器或对其他处理器不可见的地方因此volatile变量总是会返回最新的值。...原创 2018-10-14 15:59:05 · 1745 阅读 · 1 评论 -
java 线程池初步涉足
先看以下代码,是我们创建线程池的一种方式:ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(); 可以进入Executors类看一下,java创建线程池的四种方式,分别有以下四个大类:(1)newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲...原创 2018-09-15 12:25:03 · 251 阅读 · 1 评论 -
Java 确定线程池中工作线程数的大小
以问答形式展开,会更有针对性:1、工作线程是不是越多越好? 不是。a、服务器cpu核数有限,所以同时并发或者并行的线程数是有限的,所以1核cpu设置1000个线程是没有意义的。 b、线程切换也是有开销的。频繁切换线程会使性能降低。2、调用sleep()函数的时候,县城是否会占用着CPU? 不占用,sleep()函数切换时会把cpu让出来。accept()阻塞和rec...原创 2018-09-12 16:20:17 · 15255 阅读 · 0 评论 -
java 线程的几种状态
现在是jdk中java线程状态的源码。public enum State { /** * Thread state for a thread which has not yet started. */ NEW, //新建状态,该线程还没有执行start方法 /** * Thread sta...原创 2018-08-24 15:24:35 · 308 阅读 · 0 评论 -
java并发——客户端加锁机制,内置锁——面试题
看一下下面这个类,他是不是线程安全的?一眼看过去,没毛病啊,肯定安全啊。list是安全的,ListHelp中的方法是安全的,所以这个类是线程安全的。其实,这边是给你制造了一个假象,这个类并不是线程安全的,原因就是方法1的同步方法中对list进行先检查后执行的操作(一般都要求先检查后执行的操作是原子性的),但是list对象并不是你这个方法所私有的,看着list是public的,也就是说,lis...原创 2018-08-03 10:09:59 · 1781 阅读 · 0 评论 -
java ArrayList遍历时会报出ConcurrentModificationException,而CopyOmWriteArrayList不会报出的原因
首先说一下,这两个集合的区别在于,一个是线程安全的,一个不是线程安全的。底层都是用数组进行存储,加一个值的时候都会进行数据拷贝。在遍历的时候,ArrayList的迭代器Itr里面有如下属性值:Itr是内部类 int cursor; // index of next element to return int lastRet = -1; // index ...原创 2018-08-06 18:13:30 · 615 阅读 · 0 评论 -
java同步容器类的问题,vector等
大家都知道java中的同步容器类是线程安全的,但是在某些情况下可能需要额外的客户端加锁来保护复合操作。容器上的常见的复合操作是:迭代(遍历完容器中的所有容器),跳转(根据指定顺序找到当前元素的下一个个元素)以及条件运算 。最常见的例如”若没有则添加“(检查map中是否存在key值,不存在再添加)。 在同步容器类中,这些复合操作在没有客户端加锁的情况下仍然是线程安全的,但当其他线程...原创 2018-08-06 10:52:37 · 506 阅读 · 0 评论 -
java 倒计时闭锁——CountDownLatch的基本使用
CountDownLatch是一种灵活的闭锁,他可以使一个或者多个线程等待一组事件发生。闭锁状态包括一个计数器,该计数器被初始化为1个正数,表示需要等待的事件数量。countDown方法递减计数器,表示有一个事件已经发生了,而await方法等待计数器达到0,这表示所有需要等待的事件都已经发生。如果计数器的值非0,那么await会一直阻塞直到计数器为0,或者等待线程中的线程中断,或者等待超时。...原创 2018-08-10 11:07:30 · 509 阅读 · 0 评论 -
《java并发编程实战》第三章
不变性 满足同步需求的另一种方法是使用不可变对象。目前为止遇到的多线程并发问题,例如失效数据,丢失更新或者某一对象的状态不一致,这些问题的根源在于操作对象状态的可变性。如果某一个对象在被创建后其状态不能被修改,那么这个对象就被称为不可变对象。记住,不可变对象一定是线程安全的。不可变对象的设计很简单,他们只有一种状态,并且该状态是由构造函数来控制的。 Final域 在...原创 2018-07-16 09:36:02 · 292 阅读 · 0 评论 -
java线程封闭 ThreadLocal的使用
当访问共享的可变数据时,通常需要使用同步,一种避免使用同步的方式就是不共享数据。Java提供了ThreadLocal类来方便开发者们实现线程封闭,在这个ThreadLocal类中的某个值与保存值的对象关联起来。ThreadlLocal提供了get与set方法,这些方法为每一个使用该变量的线程都存着一份独立的副本,因此get总是返回当前执行线程再调用set时设置的最新值。 pack...原创 2018-07-16 09:33:12 · 261 阅读 · 0 评论 -
重入 锁
当某个线程请求由其他线程所持有的锁时,发出请求的线程会被阻塞,然而,由于内置锁是可重入的,因此如果某个线程试图获得一个已经由它自己持有的锁,那么这个请求就会成功。“重入“意味着获取锁的粒度是”线程“,而不是”调用“。重入的一种实现方法是,为每一个锁关联一个获取计数值和一个所有者线程。当计数值为0时,这个锁就被认为是没有被任何线程持有,当线程请求一个未被持有的锁时,jvm将记下锁的持有者,并...原创 2018-07-09 09:28:34 · 163 阅读 · 0 评论 -
内置锁
java提供了一种内置的锁机制来支持原子性:同步代码块(Synchronized Block),同步代码块包括了两部分:一个作为锁的对象引用,一个作为由这个锁所保护的代码块。以关键字syschronzied来修饰的方法就是一种横跨整个方法体的同步代码块,其中该同步代码块的锁就是方法调用所在的对象。静态的synchronzied方法以Class对象作为锁。 每个Java对象都可以用作一...原创 2018-07-09 09:27:02 · 1021 阅读 · 0 评论 -
复合操作
在前两节的程序中都需要包含一组原子方式执行(或者说不可分割)的操作,要避免竟态条件问题,就必须在某个线程修改该变量时,通过某种方式防止其他线程使用这个变量。从而确保其他线程只能在修改操作执行之前或者完成之后读取和修改状态,而不是在修改过程中。 如果递增操作是原子操作,那么竟态条件将不会发生,且递增操作在每次执行时都会把计数器增加1。为了确保线程安全性,“先检查后执行”(例如延迟初始...原创 2018-07-09 09:24:11 · 1224 阅读 · 0 评论 -
竟态条件
上一节讲了竟态条件,竟态条件使得最后的结果不准确,当计算的正确性取决于多个线程的交替执行时序时,那么就会发生竟态条件。换句话说,就是正确的结果取决于运气。最常见的竟态条件类型就是“先检查后执行(Check-Then-Act)”操作,即通过一个可能失效的观测结果来决定下一步的动作。 使用“先检查后执行”的一种常见情况就是延迟初始化,延迟初始化的目的是将对象的初始化操作推迟到实际被使用...原创 2018-07-09 09:14:08 · 1014 阅读 · 0 评论 -
原子性 多线程
当我们在无状态对象中增加一个状态时,会出现什么情况,假设我们希望增加一个请求数量的统计,一种常见的方式就是在对象中增加一个long类型的域,并且没处理一个请求就将这个值加一。package com.zy.test;public class StatelessDemo { private long count = 0; public void serv...原创 2018-07-09 09:10:59 · 464 阅读 · 0 评论 -
《java并发编程实战》——无状态的对象是线程安全的
在平时的项目中,每个模块都会创建多个线程,并在这些线程中调用你编写的代码,因此你需要保证你的代码是线程安全的,通常,线程安全性的需求并非来源于对线程的直接使用。例如以下方法:public class StatelessDemo { public void service() { int n = 0; int m = 1; S...原创 2018-07-08 11:53:08 · 397 阅读 · 0 评论 -
Java 通过Future来对任务进行取消
本节我们将通过Java中的Future实现对于提交的任务进行取消。ExecutorService.submit将返回一个Future来描述任务,Future拥有一个cancel方法,该方法带有一个boolean类型的参数mayInterruptIfRunning,表示取消操作是否成功(这个参数只是表示任务是否能够接收中断,而不是表示任务是否能检测并处理中断)。如果mayInterrup...原创 2018-10-14 18:15:52 · 3156 阅读 · 1 评论