
java基础
java相关技术基础
catch that elf
一辈子很短,努力的做好两件事就好;第一件事是热爱生活,好好的去爱身边的人;第二件事是努力学习,在工作中取得不一样的成绩,实现自己的价值,而不是仅仅为了赚钱;
展开
-
java并发编程(1)
什么是并发编程? 并发编程就是多个线程一起执行某个任务或逻辑。如果把一个线程比作一个工人的话,就是多个工人同时做某项工作。以提高效率。 并发一定快吗? 按照正常工人干活的例子来说,在每个工人效率相同的情况下,多个工人的速度很定大于一个工人的速度。但是在计算机并发处理时并一定比单线程处理快,原因如下: 1、多线程之间是需要获取CPU的时间片才能工作的。当线程1用完了本次分配的时间片,就会停止工作并保...原创 2019-05-08 18:59:36 · 361 阅读 · 0 评论 -
JAVA并发编程(12)-读写锁ReentrantReadWriteLock的实现分析
读写所 读写锁分为读锁和写锁两个部分。读的部分是共享的,可以多个线程同时使用。写锁时互斥的。同一时刻只有一个线程可以写。并且写的时候不允许读。 我们知道AQS维护了一个 int类型的同步状态变量state。那如何用一个变量来实现读写的复杂控制呢?使用按位分段保存。一个int类型变量有32位二进制组成。将这32位分为高16位和低16位,高16位保存读状态,低16位保存写状态。如下图 那如何快速获取...原创 2019-06-02 11:17:44 · 461 阅读 · 0 评论 -
JAVA并发编程(11)-JAVA重入锁的实现
重入锁 重入锁就是当线程A已经获取到了锁A,当再次需要获取锁A时,可以正常获取,不会被阻塞。就是一个线程可以多次获取同一个锁。synchronized 锁就是可重入的。java 1.5以后提供了ReentrantLock 实现重入锁功能。ReentrantLock 支持公平锁和非公平锁。 重进入的实现-非公平锁 前边两篇中我们提到过锁的底层实现就是 实现AQS的 tryAcquires 等方法。重...原创 2019-06-02 10:20:18 · 421 阅读 · 0 评论 -
JAVA并发编程(10)-队列同步器(AQS)的实现原理
上一篇中,我们说到了AQS封装了一些列的底层操作,包括通过阻塞队列实现阻塞的获取锁、超时获取锁、获取共享锁等。那么AQS是如何实现这些操作的呢? 阻塞队列-实现同步的关键 AQS中维护了FIFO的一个阻塞队列,在属性中保存了队列的head节点和 tail节点引用,如下: 当一个线程获取同步状态失败时,就会用当前线程构造一个队列节点,调用AQS提供的:compareAndSetTail(Node ...原创 2019-06-02 00:23:33 · 714 阅读 · 0 评论 -
java并发编程(7)-final属性的内存语义
JMM 规定的final属性的重排序规则 1)在构造函数内对一个final属性的写入,与随后把这个执行构造方法构造的对象的引用赋值给一个变量 这两个操作不能重排序。就是说一定是限制性 final属性的写入,然后才能通过引用访问构造(new)的对象。 2)第一次读去一个包含final属性的实例的引用,与随后读取final属性这两个操作不能重排序。就是说肯定是先读到实例的引用,然后才会去读final属...原创 2019-05-24 12:13:56 · 400 阅读 · 0 评论 -
JAVA并发编程(9)-JAVA中的锁及实现方式(AQS)
Lock接口 锁是用来控制多个线程访问共享资源的。在java1.5之前主要依靠synchronized 关键字来实现锁的功能。1.5之后java并发包中引入了Lock接口来实现锁功能。 Lock接口常用方法: void lock() 阻塞式获取锁 获取成功才能返回 void lockInterruptibly() 可中断获取锁 和lock 不同之处就是可以响应中断 boolean tryLo...原创 2019-05-26 18:44:11 · 661 阅读 · 0 评论 -
并发编程(6)-锁的内存语义及实现
锁的内存语义 锁的释放:JMM会把该线程对应的内地内存中的共享变量刷新到主内存中。 同volatile写 锁的获取:JMM会把该线程对应的本地内存置为无效,从而使得被监视器保护的临界区代码必须从主内存读取共享变量。 同volatile读 锁内存语义的实现 这里以ReentrantLock 实现为例。在ReentrantLock中,调用lock()方法获取锁;调用unlock()方法释放锁。Ree...原创 2019-05-21 23:49:23 · 442 阅读 · 0 评论 -
并发编程(5)-volatile内存语义及JMM实现方式
volatile特性 1)可见性 对一个 volatile 变量的读总恩能够看到之前对这个变量的写 2)原子性 对任意单个volatile变量的读写具有原子性,但是对于复合操作 volatile++没有原子性。 疑问: 读为啥能有原子性? 因为缓存一致性协议如果读了一半被修改了,就重新读? 这里A线程写一个volatile变量后,B线程读同一个volatile变量。A线程在写volati...原创 2019-05-21 23:03:24 · 428 阅读 · 0 评论 -
java并发编程(4)-指令重排序 以及java如何保证执行结果的正确性
指令成功排序 java 在编译程序以及CPU执行指令时为了提高执行效率,可能会对程序指令进行重排序。其中包括三种情况 1)java编译器在编译过程中,在不改变单线程语义(执行结果)的前提下,会对程序指令进行重排序。比如 程序里写了 int a=1;int b=2; 这两行在编译的过程中,由于改变顺序不会影响执行结果,所以可能会颠倒 两行的执行顺序。 2)现代CPU 通过指令级并行技术将多条指令重叠...原创 2019-05-15 23:23:20 · 1002 阅读 · 0 评论 -
JAVA并发编程(8)-线程基础看这一篇就够啦
CPU最小的执行单元就是线程 为什么使用多线程? 1)多核心CPU时代单线程浪费cpu,多线程可以充分利用cpu计算能力 2)提高执行效率减少程序的响应时间 线程优先级 可以通过setPriority 来设置优先级 1-10 优先级一次递增。 一般高优先级的线程获得执行的几率比低优先级的线程大。但是线程并不是严格按照优先级来执行的。比如Mac OS X 10.10,Java版本为1.7.0_71 ...原创 2019-05-24 13:16:25 · 396 阅读 · 0 评论 -
java并发编程(3)-CPU及JAVA原子操作的实现原
CPU原子操作实现方式 cpu一般用锁总线或锁缓存的方式实现原子操作。 首先每个cpu可以保证从系统中读取或写入一个字节是原子的。当一个cpu访问内存中一个字节时其他cpu不能访问这个字节。P6以及最新的处理器同一个缓存行里16/32/64位的操作是原子的,但是对于跨总线跨缓存行的数据无法保证访问的原子性,这种数据就需要用总线锁或者缓存锁来实现。 总线锁:所谓总线锁就是使用处理器提供的一个Lock...原创 2019-05-14 18:30:22 · 509 阅读 · 0 评论 -
java并发编程(2)-volatile作用和实现原理
volatile作用 volatile用于保证量在并发环境中的可见性。它不需要切换线程状态所以一般情况下效率比synchronized要高很多。一般情况下在多核CPU环境中 为了提高计算效率,每个核心都会缓存变量到cpu核心本地的缓存中,cpu 计算过程会只更新本地缓存中的变量的值,待cpu比较空闲或其他恰当的实际会将本地缓存的变量值会写到系统内存。这样一来 如果一个线程修改了缓存中的值但是还没有...原创 2019-05-14 09:51:52 · 582 阅读 · 0 评论 -
JAVA并发编程(13)-Condition接口
java的基类,Object类提供了 wait 和 notify notifyAll方法。这些方法和Synchronized关键字一起使用可以实现等待/通知木模式。Condition接口也提供了和 wait notify 相似的方法用于和Lock配合实现等待/通知模式。二者比较如下: Condition 的使用 1、通过Lock实例new 一个Condition。并传给线程 2、满足线程等待条件...原创 2019-06-02 12:39:54 · 362 阅读 · 0 评论