java并发

current包下ReentrantReadWriteLock的使用

与世无争的帅哥 提交于 2020-04-12 14:02:47
ReentrantReadWriteLock中可以生产读锁和写锁。 读锁和读锁不互斥,写锁和任何读锁或者写锁都互斥。 demo:读锁和读锁不互斥 public static void main(String[] args) { ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock(); final ReentrantReadWriteLock.ReadLock readLock = reentrantReadWriteLock.readLock(); final ReentrantReadWriteLock.WriteLock writeLock = reentrantReadWriteLock.writeLock(); for (int i = 0; i < 5; i++) { new Thread(new Runnable() { public void run() { try { readLock.lock(); System.out.println(Thread.currentThread().getName() + " 开始读取数据"); TimeUnit.SECONDS.sleep(5); System.out.println(Thread.currentThread()

java并发之原子性、可见性、有序性

人走茶凉 提交于 2020-03-06 13:38:17
原子性 原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行。 在Java中,对基本数据类型的变量的读取和赋值操作是原子性操作,即这些操作是不可被中断的,要么执行,要么不执行。 上面一句话虽然看起来简单,但是理解起来并不是那么容易。看下面一个例子: 请分析以下哪些操作是原子性操作: 1 x = 10; //语句1 2 y = x; //语句2 3 x++; //语句3 4 x = x + 1; //语句4 咋一看,有些朋友可能会说上面的4个语句中的操作都是原子性操作。其实只有语句1是原子性操作,其他三个语句都不是原子性操作。 语句1是直接将数值10赋值给x,也就是说线程执行这个语句的会直接将数值10写入到工作内存中。 语句2实际上包含2个操作,它先要去读取x的值,再将x的值写入工作内存,虽然读取x的值以及 将x的值写入工作内存 这2个操作都是原子性操作,但是合起来就不是原子性操作了。 同样的,x++和 x = x+1包括3个操作:读取x的值,进行加1操作,写入新的值。 所以上面4个语句只有语句1的操作具备原子性。 也就是说,只有简单的读取、赋值(而且必须是将数字赋值给某个变量,变量之间的相互赋值不是原子操作)才是原子操作。 不过这里有一点需要注意:在32位平台下,对64位数据的读取和赋值是需要通过两个操作来完成的,不能保证其原子性

并发编程-Future模式

断了今生、忘了曾经 提交于 2019-11-30 01:13:42
1.Future模式有点类似商品订单。比如在网上进行购物,当看中某一件商品时,就可以提交订单。提交订单完毕在家等候送货上门。卖家根据订单取货、发货,并配送到顾客手中。大部分情况下,卖家处理订单没那么快,可能需要几天时间。而这段时间买家不必再家里等候,可以做其他事情。 将此类推到程序设计中,当某一段程序提交了一个请求,期望得到一个答复。但非常不幸的是,服务程序对这个请求的处理可能非常慢。在传统的单线程环境下,调用函数是同步的,也就是说它必须要等到服务程序返回结果后,才能够进行其他处理。而在Future模式下,调用方式该为异步,而原来等待返回的时间段,在主调用函数中,则可以用于处理其他事物。传统程序的调用流程如下图所示。 图1-1 传统串行程序调用流程 采用Future模式设计程序,调用流程如下。 图1-2 Future模式流程图 表1-3 Future模式的主要参与者 参与者 作用 Main 系统启动,调用Client发出请求你 Client 返回Data对象,立即返回FutureData,并开启ClientThread线程装配RealData Data 返回数据的接口 Future Future数据,构造很快,但是是一个虚拟的数据,需要装配RealData RealData 真实数据,其构造是比较慢的 2.Future模式的代码实现 2.1Main函数的实现