![](https://img-blog.csdnimg.cn/20201014180756780.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
Java
阳小林
这个作者很懒,什么都没留下…
展开
-
AQS实现分析
下文将从实现角度分析AQS是如何完成线程同步,主要包括:同步队列、独占式同步状态获取与释放、共享式同步状态获取与释放、超时获取同步状态等AQS的核心数据结构模板方法。同步队列AQS依赖同步队列(一个FIFO双向队列)来完成同步状态的管理。当前线程获取同步状态失败时,AQS会将当前线程以及等待状态等信息构造成一个节点(Node)并且将其加入到同步队列中,同时会阻塞当前线程,当同步状态释放时,会把首节点原创 2017-01-23 17:40:32 · 8307 阅读 · 1 评论 -
Thread.join()的使用
如果一个线程A执行了thread.join()方法,表示,当前线程A等待thread线程终止之后才从thread.join()返回。线程Thread除了提供join()方法之外,还提供了join(long millis)和join(long millis,int nanos)两个具备超时特性的方法。如果线程thread在给定的超时时间里没有终止,那么将会从该超时方法中返回。public class原创 2017-01-20 15:18:53 · 4099 阅读 · 0 评论 -
重入锁--ReentrantLock
重入锁,支持冲进入的锁,表示该锁能够支持一个线程对资源的重复加锁。同时,该锁还支持获取锁时的公平和非公平性选择实现重进入是指任意线程在获取到锁之后能够再次获取该锁而不会被锁所阻塞。该特性的实现需要解决下面两个问题 1. 线程再次获取锁。锁需要去识别获取锁的线程是否为当前占据锁的线程,如果是,则再次获取成功 2. 锁的最终释放。线程重复n次获取锁,随后在第n次释放该锁后,其他线程能够获取原创 2017-02-10 18:03:19 · 333 阅读 · 0 评论 -
ThreadLocal作用与实现
ThreadLocal用于提供线程内部的局部变量,这些变量与它们的正常对象不同,每个线程访问一个单独属于自己的,独立的变量的初始副本。对于ThreadLocal中那些希望将状态与线程相关联的静态字段,通常是private的,例如 用户Id或者事务ID。例如,下面的类为每个线程生成一个本地唯一标识符,线程的id是在第一次调用ThreadId.get()时分配的,并在后续调用中保持不变。public c原创 2017-01-22 18:07:00 · 1803 阅读 · 0 评论 -
Lock接口与Synchronized关键字的区别
首先,Lock接口与Synchronized关键字都能提供相同的同步功能,只是Lock接口在使用时,需要显示地获取和释放锁。从而使Lock接口没有像Synchronized关键字那样隐式获取锁来的便捷,然而,Lock接口可以拥有获取锁和释放锁的可操作性、可中断的获取锁以及超时获取锁等多种Synchronized关键字不具备的特性。具体如下: 特性 描述 尝试非阻塞地获取锁 当前线程尝试原创 2017-01-23 15:37:59 · 1319 阅读 · 0 评论 -
读写锁--ReentrantReadWriteLock
概念读写锁在同一时刻允许多个读线程访问,但是在写线程访问时,所有的读线程和其他写线程均被阻塞。读写锁维护着一对锁:一个读锁和一个写锁,通过分离读锁和写锁,提高了并发性能。实现类ReentrantReadWriteLock是ReadWriteLock接口的具体实现,其主要有以下特性: 特性 说明 公平性选择 支持非公平(默认)和公平的获取方式,吞吐量还是非公平优于公平 重进入 该原创 2017-02-13 16:26:16 · 477 阅读 · 0 评论 -
Fork/Join框架
概述Fork/Join框架是一个Java 7提供的用于并行执行任务的框架,是一个把大型任务分割成若干个小任务最终汇总每个小任务结果后得到大任务结果的框架。工作窃取算法工作窃取算法是指某个线程从其他队列里窃取任务来执行。使用工作窃取算法可以充分利用线程进行并行计算,减少了线程间的竞争。但是在某些情况下还是存在竞争,比如双端队列里只有一个任务时。并且该算法会消耗更多的系统资源,比如创建多个线程和双端队原创 2017-02-21 17:55:06 · 936 阅读 · 0 评论 -
java中的并发工具类
概述CountDownLatch:允许一个或多个线程 等待其他线程完成操作CyclicBarrier:当一组线程达到同步点时被阻塞,直到最后一个线程到达同步点时,所有被拦截的线程才会继续运行Semaphore:信号量,用来控制同时访问特定资源的线程数量,它通过协调各线程以保证合理的使用公共资源Exchanger:用于进行线程间的数据交换CountDownLatch原创 2017-03-01 11:18:22 · 389 阅读 · 0 评论 -
Condition接口
任意一个java对象,都拥有一组监视器方法(定义在Object上),主要包括wait()、wait(long timeout)、notify()、notifyAll()方法,这些方法与Synchronized同步关键字配合使用,可以实现等待/通知模式。Condition接口也提供了类似Object的监视器方法,与Lock配合可以实现等待/通知模式。二者的区别如下: 对比项 Obje原创 2017-02-14 16:40:20 · 1146 阅读 · 0 评论 -
阻塞队列--BlockingQueue
概述阻塞队列是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移除方法。 1. 支持阻塞的插入方法:当队列满时,队列会阻塞插入元素的线程,直到队列不满 2. 支持阻塞的移除方法:当队列为空时,获取元素的线程会等待队列变为非空。阻塞队列适用与生产者和消费者的场景。在阻塞队列不可用时(满了或者为空),这两个附件操作提供了4中处理方式:抛出异常,返回特殊值、一直阻原创 2017-02-21 14:18:12 · 577 阅读 · 0 评论 -
Java中的原子操作类
概述java.util.concurrent.atomic包一共提供了13个类,属于4中类型的原子更新方式:原子更新基本数据类型、原子更新数组、原子更新引用、原子更新属性。原子更新基本类型 >java.util.concurrent.atomic包提供了以下3个类: AtomicBoolean:原子更新布尔类型 AtomicInteger : 原子更新整型 AtomicLon原创 2017-02-24 15:37:59 · 2972 阅读 · 0 评论 -
Java线程池
使用线程池的好处 1. 降低资源消耗。通过重复利用已创建的线程降低创建线程和销毁造成的消耗 2. 提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。 3. 提高线程的可管理性。线程池的处理流程线程池判断核心线程池是否都在执行任务。如果不是,则创建一个新的线程来执行任务。如果核心线程池里的线程都在执行任务,那么则进入下一个流程线程池判断工作队列原创 2017-03-03 16:34:20 · 386 阅读 · 0 评论 -
HashMap 多线程处理之 Fail-Fast机制
原文出处:HashMap 多线程处理之 Fail-Fast机制 作者 alex_lo Fail-Fast机制: 我们知道java.util.HashMap不是线程安全的,因此如果在使用迭代器的过程中有其他线程修改了map,那么将抛出ConcurrentModificationException,这就是所谓fail-fast策略。 这一策略在源码中的实现是通过modCount域,modCount顾名转载 2017-03-03 17:03:20 · 2162 阅读 · 0 评论 -
多线程的等待/通知机制
等待/通知机制,是指一个线程A调用了对象O的wiat方法进入等待状态,而另一个线程B调用了对象O的notify或者notifyAll方法,线程A收到通知后从对象O的wait方法返回,进而执行后续操作。等待/通知的实例分析在下面的代码中,创建两个线程,WaitThread和NotifyThread。WaitThread负责检查flag是否为false,如果符号要求,则进行后续操作,否则在lock上等待原创 2017-01-19 18:06:39 · 2896 阅读 · 1 评论 -
jdk1.8中ConcurrentLinkedQueue的实现原理
原文链接ConcurrentLinkedQueue源码分析 作者 周盛帆概述ConcurrentLinkedQueue是一个基于链接节点的无界线程安全队列,采用FIFO的规则对节点进行排序,当我们添加一个元素的时候,它会添加到队列的尾;当我们获取一个元素时,它会返回队列头部的元素。用CAS实现非阻塞的线程安全队列。 ConcurrentLinkedQueue 的非阻塞算法实现主要可概括为下面几点:转载 2017-02-17 15:57:50 · 4170 阅读 · 3 评论 -
Jdk1.8中的LinkHashMap实现原理
概述LinkedHashMap继承自HashMap,是Hash表和链表的实现,并且依靠着双向链表保证了迭代顺序是插入的顺序。如果 一个key重新插入到LinkedHashMap中,那么这个插入顺序是无效的,也就是说,如果m.put(K,V)时,调用m.containsKey(k),将会返回true,更新value值,但是顺序不变。public class TestLinkHashMap {原创 2016-12-23 11:14:45 · 1404 阅读 · 1 评论 -
Thread.interrupted()与Thread.isInterrupted()的区别
调用Thread.interrupt()方法并不能真正停止线程,只是在当前线程做了一个中断的状态标志。public class MyThread extends Thread{ @Override public void run() { for (int i = 0; i < 100; i++) { super.run();原创 2017-01-04 16:04:30 · 11477 阅读 · 7 评论 -
中断线程的办法
我们知道调用Thread的interrupt方法,并不能真正中断线程,只是给线程做了个中断的状态标记,那么如何中断线程呢?先看如下的代码:public class MyThread extends Thread{ @Override public void run() { try { for (int i = 0; i <1000; i++) {原创 2017-01-04 16:23:47 · 289 阅读 · 0 评论 -
线程的优先级
现在操作系统基本采用时分的形式调度运行的线程,操作系统会分出一个个时间片,线程会分配到若干的时间片,当线程的时间片用完了,就会执行发生线程调度,并等待这下次时间片的分配。线程分配到的时间片的多少,直接决定了线程占用cpu资源的多少,而线程优先级则决定了线程需要多或者少分配cpu资源的属性。线程通过setPriority方法进行优先级的设定: public final void setPrior原创 2017-01-04 16:51:53 · 457 阅读 · 0 评论 -
volatile原理与作用
此文乃《java并发编程的艺术》读书笔记。购买链接 同时参考文章:Java 理论与实践: 正确使用 Volatile 变量定义 java编程语言允许线程之间共享变量,为了保证共享变量能够被准确和一致的更新,那么线程应该确保通过排他锁单独获得这个变量。Volatile的实现原理 处理器为了提高处理速度,不直接和内存进行通讯,而是先将系统内存的数据读到内部缓存(L1,L2或其他)后再进行操作原创 2017-01-04 18:58:59 · 867 阅读 · 0 评论 -
Java位运算符总结
1. 左移(<<) 例如: 2 << 2,则是将数字2左移2位计算过程:2<< 2首先把2转换为二进制数字0000 0000 0000 0000 0000 0000 0000 0010,然后把该数字高位(左侧)的两个零移出,其他的数字都朝左平移2位,最后在低位(右侧)的两个空位补零。则得到的最终结果是0000 0000 0000 0000 0000 0000 0000 1000,则转换为十进制是原创 2016-12-27 17:15:35 · 538 阅读 · 0 评论 -
Synchronized的实现与原理
此文乃《Java并发编程的艺术》读书笔记。购买链接实现的基础 java中的每一个对象都可以作为锁 其表现形式为: 1.对于普通同步方法,锁是当前类的实例对象 2.对于静态同步方法,锁是当前类的Class对象 3.对于同步代码块,锁是synchronized括号里配置的对象synchronized在JVM的实现 JVM基于进入和退出Monitor对象来实现方法同步和代原创 2017-01-05 11:30:17 · 560 阅读 · 0 评论 -
原子操作的实现与原理
在java中可以通过锁和CAS操作来实现原子操作CAS实现原子操作CAS自旋的基本思路是:循环进行CAS操作,直到成功为止下面代码演示了非线程安全的计数器和采用CAS操作的线程安全计数器public class Counter { private AtomicInteger actomicI = new AtomicInteger(0); private int i = 0;原创 2017-01-05 16:20:22 · 560 阅读 · 0 评论 -
偏向锁和轻量级锁
偏向锁为了让线程获取锁的代价减少,从而引入了偏向锁。当一个线程访问同步块并获取锁的时候,会在对象头和栈帧中的琐记录里存储锁偏向的线程ID,以后线程在进入同一个同步块时,不需要进行CAS操作,来加锁和解锁。只需简单的测试对象头的Mark Word里是否存储这指向当前线程的偏向锁。如果测试成功,表示线程已经获得锁。如果测试失败,需要再次测试对象头的Mark Word里的偏向锁标识是否设置为1(表示原创 2017-01-05 17:57:50 · 1271 阅读 · 1 评论 -
Java内存模型
基础概念 在并发编程中,需要处理两个关键的问题: 1. 线程之间如何通讯 2. 线程之间如何同步 在命令式编程中,线程通讯有两种方式: 1. 共享内存 2. 消息传递在共享内存的并发模型里,线程之间共享程序的公共状态,通过写-读内存中的公共状态,进行隐式通讯在消息传递的并发模型里,线程之间没有公共状态,线程之间必须通过发送消息进行显式通讯 在共享内存模型中,原创 2017-01-16 18:01:32 · 314 阅读 · 0 评论 -
线程的状态
状态名称 说 明 NEW 初始状态,线程被构建,但是还没有调用start方法 RUNNABLE 运行状态,Java线程将操作系统中的就绪和运行两种状态统称为“运行中” BLOCKED 阻塞状态,表示线程阻塞于锁 WAITING 等待状态,表示线程进入等待状态,进入该状态表示当前线程需要等待其他线程做出一些特定动作(通知或中断) TIME_WAITING 超时原创 2017-01-18 14:04:26 · 357 阅读 · 0 评论 -
Daemon线程
Daemon线程是一种支持型线程,因为它主要用作程序中后台调度已经支持性工作。当一个JVM中不存在非daemon线程的时候,JVM将会退出。可以通过Thread.setDaemon(true)将线程设置位Daemon线程。但是必须在启动线程之前设置,不能在启动线程后设置。在构建Daemon线程时,不能依靠finally块中的内容来确保执行关闭或者清理资源的逻辑。因为Daemon线程一终止,JVM就会原创 2017-01-18 14:10:10 · 330 阅读 · 0 评论 -
Executor框架
结构组成Executor主要由3个部分组成:1. 任务。包括被执行任务需要的Runnable接口或者Callable接口 2. 任务的执行。包括执行任务的核心接口Executor以及继承自Executor的ExecutorService接口。Executor接口有两个关键类实现了ExecutorService接口的类:ThreadPoolExecutor和ScheduleThreadPoolEx原创 2017-03-07 17:18:15 · 823 阅读 · 0 评论