随笔分类 -  多线程

Java并发编程的艺术(十)Lock接口
摘要:1、JDK5之后,并发包中新增了Lock接口(以及相关实现类)用来实现锁功能,它提供了与synchronized关键字类似的同步功能,只是在使用时需要显示地获取和释放锁。 2、synchronized关键字将会隐式地获取锁,但是它将锁的获取和释放固化了,也就是先获取再释放。这种方式简化了同步的管理, 阅读全文
posted @ 2019-08-04 09:30 逍遥1989 阅读(168) 评论(0) 推荐(0)
Java并发编程的艺术(六)happens-before
摘要:1、happens-before是JMM最核心的概念,JSR-133使用happens-before来指定两个操作之间的执行顺序。 2、如果A happens-before B,那么: (1)对程序员来说:A的执行结果对B可见,并且A的执行顺序排在B之前。 (2)对编译器和处理器来说:不一定要按照程 阅读全文
posted @ 2019-07-21 16:16 逍遥1989 阅读(172) 评论(0) 推荐(0)
Java并发编程的艺术(五)重排序
摘要:1、重排序:指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。 2、数据依赖性:两个操作访问同一个变量,且者两个操作中有一个为写操作,此时这两个操作之间就存在数据依赖性。 (1)分类:写后读、写后写、读后写。 (2)编译器和处理器在重排序时,会遵守数据依赖性,不会改变存在数据依赖关 阅读全文
posted @ 2019-07-21 15:25 逍遥1989 阅读(237) 评论(0) 推荐(0)
Java并发编程的艺术(五)Java内存模型
摘要:1、并发编程模型的两个关键问题:线程之间的通信和同步。 2、并发线程模型有两种: (1)共享内存:线程之间有公共状态,通过读-写内存中的公共状态进行隐式通信,显示同步。 (2)消息传递:线程之间没有公共状态,必须通过发送消息进行显示通信,隐式同步。 3、Java的并发采用共享内存模型,线程间的通信总 阅读全文
posted @ 2019-07-20 12:10 逍遥1989 阅读(159) 评论(0) 推荐(0)
Java并发编程的艺术(四)原子操作的实现原理
摘要:1、原子操作:不可被中断的一个或一系列操作。 2、处理器实现原子操作 (1)使用总线锁保证原子性:LOCK#信号锁住总线,处理器独占共享内存。 (2)通过缓存锁来保证原子性:指内存区域如果被缓存在处理器的缓存行中,并且在Lock操作期间被锁定,当它执行锁操作回写到内存时,处理器不在总线上声言LOCK 阅读全文
posted @ 2019-07-20 11:44 逍遥1989 阅读(211) 评论(0) 推荐(0)
Java并发编程的艺术(三)synchronized的应用
摘要:1、利用synchronized实现同步的基础:Java中的每一个对象都可以作为锁。 (1)对于普通同步方法,锁是当前实例对象。 (2)对于静态同步方法,锁是当前类的Class对象。 (3)对于同步方法块,锁是Synchronized括号里配置的对象。 2、synchronized在JVM中的实现原 阅读全文
posted @ 2019-07-20 11:07 逍遥1989 阅读(137) 评论(0) 推荐(0)
Java并发编程的艺术(二)volatile的应用
摘要:1、volatile是轻量级的synchronized,它在多处理器开发中保证了共享变量的可见性。 2、为了提高处理器速度,处理器不直接和内存进行通信,而是先将系统内存的数据读到内部缓存(L1,L2或其他)后再进行操作,但操作完不知道何时会写到内存。 3、volatile保证可见性的原理是利用处理器 阅读全文
posted @ 2019-07-20 10:30 逍遥1989 阅读(154) 评论(0) 推荐(0)
Java并发编程的艺术(一)并发编程的挑战
摘要:1、上下文切换 (1)定义:CPU通过不停地切换线程来实现多线程的执行,一个任务从暂存到重新加载的过程就是一次上下文切换。 (2)减少上下文切换方法:无锁并发编程、CAS算法、使用最少线程和使用协程。 2、死锁的处理 (1)避免一个线程同时获取多个锁。 (2)尽量保证每个锁只占用一个资源。 (3)尝 阅读全文
posted @ 2019-07-05 21:46 逍遥1989 阅读(183) 评论(0) 推荐(0)
Executor框架
摘要:1、线程不是越多越好,因为Java线程的创建和销毁都需要一定的开销,线程越多,会消耗大量的计算资源(包括时间和内存等),最终会导致系统处于高负荷状态而崩溃。 2、线程的工作单元包括Runnable和Callable,执行机制则由Executor框架提供。 3、Executor框架由3部分组成:(1) 阅读全文
posted @ 2019-05-19 17:06 逍遥1989 阅读(131) 评论(0) 推荐(0)
线程池实现原理
摘要:1、当向线程池提交一个任务之后,线程池的处理流程如下: (1)判断当前核心线程数量是否大于最大值,否则创建一个新线程来执行任务,是则将该线程加入阻塞队列,进入下一步。 (2)判断当前阻塞队列是否已满,否则将任务存储到队列,是则进入下一步。 (3)判断当前线程池中的线程是否达到最大值,否则创建一个新线 阅读全文
posted @ 2019-05-17 20:01 逍遥1989 阅读(812) 评论(0) 推荐(0)
线程池设计
摘要:1、创建一个阻塞队列 (1)可以使用链表实现 (2)设置一个最大容量 (3)定义一个插入方法,队列满则阻塞;定义一个移除方法,队列空则阻塞。 2、创建一组线程 (1)每个线程运行时从阻塞队列获取任务执行。 (2)线程可以被中断。 3、执行和终止方法实现 (1)调用执行方法,线程池往阻塞队列插入一个任 阅读全文
posted @ 2019-05-17 19:12 逍遥1989 阅读(159) 评论(0) 推荐(0)
死锁相关介绍
摘要:1、多线程中的死锁,指两个或多个线程之间,由于互相持有对方需要的锁,循环依赖导致彼此一直处于阻塞的状态。 2、定位死锁最常见的方式就是利用jstack等工具获取线程栈,然后定位互相之间的依赖关系,进而找到死锁。 3、如果程序运行时发生了死锁,绝大多数情况下都是无法在线解决的,只能重启、修正程序本身问 阅读全文
posted @ 2019-04-23 08:45 逍遥1989 阅读(205) 评论(0) 推荐(0)
线程相关的sleep()、yield()、wait()、join()方法介绍
摘要:1、Thread.sleep()与Thread.yield()都会暂缓当前线程执行,给其他线程执行机会(sleep会忽略优先级,yield则只会给优先级相同或者更高的线程),不会释放锁,只会释放CPU。 2、sleep()会让线程进入阻塞状态,yield()则不会(此时线程为就绪状态)。yield( 阅读全文
posted @ 2019-04-21 17:04 逍遥1989 阅读(666) 评论(0) 推荐(0)
线程的创建方式比较
摘要:1、创建一个线程一般有三种方式:继承Thread类、实现Runnable接口和实现Callable接口。 2、实现Runnable接口与继承Thread类相比的好处: (1)可以避免继承Thread类单继承的局限性。 (2)线程分为两部分,线程对象和线程任务。继承Thread类将两部分耦合在一起,线 阅读全文
posted @ 2019-04-20 17:55 逍遥1989 阅读(253) 评论(0) 推荐(0)
线程的生命周期
摘要:1、Java5以后,线程生命周期的不同状态被明确定义在枚举类Java.lang.Thread.State中,分别是: (1)NEW(新建) (2)RUNNABLE(就绪) (3)BLOCKED(阻塞) (4)WAITING(等待) (5)TIMED_WAIT(计时等待) (6)TERMINATED( 阅读全文
posted @ 2019-04-13 11:33 逍遥1989 阅读(194) 评论(0) 推荐(0)