架构师养成记--2脏读

在我们设计程序的时候要考虑问题的整体,不然很容易出现脏读,看示例

 1 /**
 2  * 业务整体需要使用完整的synchronized,保持业务的原子性。
 3  * @author alienware
 4  *
 5  */
 6 public class DirtyRead {
 7
 8     private String username = "bjsxt";
 9     private String password = "123";
10
11     public synchronized void setValue(String username, String password){
12         this.username = username;
13
14         try {
15             Thread.sleep(2000);
16         } catch (InterruptedException e) {
17             e.printStackTrace();
18         }
19
20         this.password = password;
21
22         System.out.println("setValue最终结果:username = " + username + " , password = " + password);
23     }
24
25     public void getValue(){
26         System.out.println("getValue方法得到:username = " + this.username + " , password = " + this.password);
27     }
28
29
30     public static void main(String[] args) throws Exception{
31
32         final DirtyRead dr = new DirtyRead();
33         Thread t1 = new Thread(new Runnable() {
34             @Override
35             public void run() {
36                 dr.setValue("z3", "456");
37             }
38         });
39         t1.start();
40         Thread.sleep(1000);
41
42         dr.getValue();
43     }
44
45
46
47 }

在getValue方法前加synchronized关键字可以避免脏读。否则打印出来的结果是下图那样的:

实际我们先要的结果应该是这样的:

二、数据库的ACID

这里先关注一下ORACLE的一致性读的特性:举个例子,有A和B两个人,A在上午9点的时候对一张很大的表进行查询操作,假设这个查询需要10分钟,B在9点05分的时候对A要查询的这条记录进行了DML操作,将原来的数据值为1改成了2,那么A在9点10分得到的结果一定是1,而不会是2.(做DML操作之前会把原来的值放到UNDO里,A拿到的是UNDO里的值,也有可能抛出snapshot too old异常,但绝不可能把2返回给A)

时间: 2024-10-19 22:02:12

架构师养成记--2脏读的相关文章

专访京东孙海波:大牛架构师养成记及电商供应链中区块链技术的应用(转)

http://geek.csdn.net/news/detail/237595 编者按:每个人的成长曲线不同,有的人在研究生之时就已有相当知名的产品和框架,从而在接下来的工作中一路顺风顺水,有的人缺需要经历一个又一个的坑才能成长,不管是前者的聪明高效,还是后者的笨鸟先飞,他们都是在迈着脚步不断地向前.不妨,我们停下脚步看下一些同行,以激励自己更好地前行.CSDN与你相约SDCC 2017之区块链技术实战线上峰会. 2017年9月23日,SDCC 2017之区块链技术实战线上峰会即将强势来袭,本次

架构师养成记--31.Redis的String类型

Redis一共分为五种基本数据类型:String.Hash.List.Set.ZSet String类型是包含很多张类型的特殊类型,并且是二进制安全的.比如对序列化的对象进行存储,比如一张图片进行二进制存储,比如一个简单的字符串数值等等. Set和get方法的使用 设置值:set name sgm (多次设置name值,后一次会覆盖前一次) 取值 get name 删除值:del name setnx,nx的意思就是not exists:不覆盖赋值,如上例,如果name存在就不设置了. sete

架构师养成记--14.重入锁ReentrantLock 和 读写锁 ReentrantReadWriteLock

ReentrantLock 有嗅探锁定和多路分支等功能,其实就是synchronized,wait,notify的升级. this锁定当前对象不方便,于是就有了用new Object()来作为锁的解决方案,后面jdk干脆就提供了一个Lock类. 伪代码: Lock lock = new ReentrantLock();//新建一个lock Condition condition = lock.newCondition();//获取条件 method1(){ try{ lock.lock(); 代

架构师养成记--26.vi/vim相关操作

vi/vim命令模式插入模式 aio编辑模式 : aio就是vi/vim的插入模式命令    作用a         在光标后附加文本A         在本行末附加文本i         在光标钱插入文本I         在本行开始插入文本o        在光标下插入行O        在光标上插入行 定位命令set number 设置行号(set nu)set nonu 取消行号如果想选择跳转到指定行.直接进入编辑模式,输入行号即可 命令         作用h.方向左键    移动一个

架构师养成记--5.线程之间的通信

用wait和notify来实现线程之间的通信,这两个方法是object方法,这两个方法必须要配合synchronized使用.wait方法释放锁,notify不释放锁. 原始线程通信方式 1 import java.util.ArrayList; 2 import java.util.List; 3 4 public class ListAdd1 { 5 6 7 private volatile static List list = new ArrayList(); 8 9 public voi

架构师养成记--15.Disruptor并发框架

一.概述 disruptor对于处理并发任务很擅长,曾有人测过,一个线程里1s内可以处理六百万个订单,性能相当感人. 这个框架的结构大概是:数据生产端 --> 缓存 --> 消费端 缓存中的数据是主动发给消费端的,而不是像一般的生产者消费者模式那样,消费端去缓存中取数据. 可以将disruptor理解为,基于事件驱动的高效队列.轻量级的JMS disruptor学习网站:http://ifeve.com/disruptor-getting-started 二.开发流程 1.建Event类(数据

架构师养成记--6.单例和多线程、ThreadLocal

一.ThreadLocal 使用wait/notify方式实现的线程安全,性能将受到很大影响.解决方案是用空间换时间,不用锁也能实现线程安全. 来看一个小例子,在线程内的set.get就是threadLocal 1 public class ConnThreadLocal { 2 3 public static ThreadLocal<String> th = new ThreadLocal<String>(); 4 5 public void setTh(String value

架构师养成记--3.synchronized细节问题

一.synchronized有锁重入的特点,某个线程得到对象的锁后,再次请求此对象可以再次得到改对象的锁.如下示例,在method1中调用method2,在method2中调用method3,而method1.method2和method3都是加了synchronized关键字的. 1 /** 2 * synchronized的重入 3 * @author alienware 4 * 5 */ 6 public class SyncDubbo1 { 7 8 public synchronized

架构师养成记--线程基础

为什么要拿线程开头呢?因为线程太重要了,先不说工作中有多重要,单是和money直接挂钩的开发工程师面试就必问题,要是面试没问相关问题的话,要么是应聘者太菜面试官懒得问了,要么是公司太菜,根本不关心多线程的问题. 一.线程安全问题 当多个线程访问某一个类的时候,这个类都能表现出正确的行为,那么这个类就是线程安全的. synchronized可以加在任意对象及方法上加锁,加锁的这段代码就成为互斥区或者临界区 下面是关于线程安全的一个小示例,关键点就在synchronized这个词上 1 import