使用synchronized(非this对象)同步代码块解决脏读问题
首先通过示例来学习验证多个线程调用同一个方法时随机的。
package syn_out_asyn;import java.util.ArrayList; import java.util.List;/*** Created by Administrator on 2017/1/19 0019.*/ public class MyList {private List list = new ArrayList();synchronized public void add(String username){System.out.println("ThreadName="+Thread.currentThread().getName()+"执行了add方法");list.add(username);System.out.println("ThreadName="+Thread.currentThread().getName()+"退出了add方法");}synchronized public int getSize(){System.out.println("ThreadName= "+Thread.currentThread().getName()+"执行了getSize方法");int sizeValue= list.size();System.out.println("ThreadName= "+Thread.currentThread().getName()+"退出了getSize方法");return sizeValue;} }
package syn_out_asyn;/*** Created by Administrator on 2017/1/19 0019.*/ public class ThreadA extends Thread {private MyList list;public ThreadA (MyList list){super();this.list = list;}public void run(){for(int i=0;i<10000;i++){list.add("ThreadA"+(i+1));}} }
package syn_out_asyn;/*** Created by Administrator on 2017/1/19 0019.*/ public class ThreadB extends Thread {private MyList list;public ThreadB(MyList list){super();this.list = list;}public void run(){for(int i=0;i<10000;i++){list.add("threadB"+(i+1));}} }
package syn_out_asyn;/*** Created by Administrator on 2017/1/19 0019.*/ public class Run {public static void main(String[] args){MyList myList = new MyList();ThreadA threadA = new ThreadA(myList);threadA.setName("A");threadA.start();ThreadB threadB = new ThreadB(myList);threadB.setName("B");threadB.start();} }
执行结果: ThreadName=A执行了add方法 ThreadName=A退出了add方法 ThreadName=A执行了add方法 ThreadName=A退出了add方法 ThreadName=A执行了add方法 ThreadName=A退出了add方法 ThreadName=B执行了add方法 ThreadName=B退出了add方法 ThreadName=B执行了add方法 ThreadName=B退出了add方法 ThreadName=B执行了add方法 ThreadName=B退出了add方法
从结果来看,同步块中的代码是同步打印的,当前线程的执行和退出时成对出现的。但线程A和线程B的执行却是异步的,这就有可能出现脏读的环境。由于线程执行的方法的顺序不确定,所以当A和B两个线程执行带有分之判断的方法时,就会出现逻辑上的错误,有可能出现脏读。
package t9;import java.util.ArrayList; import java.util.List;/*** Created by Administrator on 2017/1/20 0020.*/ public class MyOneList {private List list = new ArrayList();synchronized public void add(String data){list.add(data);}synchronized public int getSize(){return list.size();} }
package t9;/*** Created by Administrator on 2017/1/20 0020.*/ public class MyService {public MyOneList addServiceMethod(MyOneList list ,String data) {try {if (list.getSize() < 1) {Thread.sleep(2000);//模拟从远程话费2秒取回数据 list.add(data);}} catch (InterruptedException e) {e.printStackTrace();}return list;} }
package t9;/*** Created by Administrator on 2017/1/20 0020.*/ public class MyThread1 extends Thread {private MyOneList list;public MyThread1(MyOneList list){super();this.list=list;}public void run(){MyService myService = new MyService();myService.addServiceMethod(list,"A");} }
package t9;/*** Created by Administrator on 2017/1/20 0020.*/ public class MyThread2 extends Thread {private MyOneList list;public MyThread2(MyOneList list){super();this.list=list;}public void run(){MyService myService = new MyService();myService.addServiceMethod(list,"B");} }
package t9;/*** Created by Administrator on 2017/1/20 0020.*/ public class Run {public static void main(String [] args) throws InterruptedException {MyOneList list = new MyOneList();MyThread1 thread1 = new MyThread1(list);thread1.setName("A");thread1.start();MyThread2 thread2 = new MyThread2(list);thread2.setName("B");thread2.start();Thread.sleep(6000);System.out.println("listSize="+list.getSize());} }
运行结果: listSize=2
脏读出现了,原因是两个线程以异步的方式返回list参数的size()大小,解决的办法就是同步化。
修改MyService.java
package t9;/*** Created by Administrator on 2017/1/20 0020.*/ public class MyService {public MyOneList addServiceMethod(MyOneList list ,String data) {try {synchronized (list) {if (list.getSize() < 1) {Thread.sleep(2000);//模拟从远程话费2秒取回数据 list.add(data);}}} catch (InterruptedException e) {e.printStackTrace();}return list;} }
运行结果: listSize=1
由于list参数对象在项目中是一份实例,是单例的,而且也正需要对list参数的getSize()方法做同步的调用,所以就对list参数进行同步处理。
结论:synchronized(非this对象x):格式的写法是将x对象本身作为“对象监视器”
转载于:https://www.cnblogs.com/dream-to-pku/p/6308620.html
使用synchronized(非this对象)同步代码块解决脏读问题相关推荐
- 同步代码块解决线程安全
案例:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果. 代码: package com.learn;class ThreadDemo01 implements Runnab ...
- 记录一次关于synchronized同步代码块的问题
本人在学习过程中在一些书籍上关于synchroinzed同步代码块的解释总是如下 synchronized(obj){ --}在使用同步代码块时锁住了obj对象其他线程同时无法访问obj对象, 这很容 ...
- java中synchronized(同步代码块和同步方法)详解及区别
问题的由来: 看到这样一个面试题: ? 1 2 3 4 5 6 //下列两个方法有什么区别 public synchronized void method1(){} public void metho ...
- Java20-day11【实现多线程(进程、线程-调度-控制-生命周期)、线程同步(同步代码块、线程安全、Lock)、生产者消费者(模式概述、案例)】
视频+资料[链接:https://pan.baidu.com/s/1MdFNUADVSFf-lVw3SJRvtg 提取码:zjxs] Java基础--学习笔记(零起点打开java世界的大门)--博 ...
- java锁方法和锁代码块_java的同步方法和同步代码块,对象锁,类锁区别
/** * @author admin * @date 2018/1/12 9:48 * 做用在同一个实例对象上讨论 * synchronized同步方法的测试 * 两个线程,一个线程调用synchr ...
- cookie里面用到的关键字_晓龙吊打面试官系列:synchronized关键字入门(同步方法与同步代码块)...
文章目录 一. 线程安全问题 二.synchronized简介 1) 原子性 2) 可见性 3) 有序性 4)可重入 1. 什么是synchronized 2.什么是同步 3.synchronized ...
- 同步代码块Synchronized笔记
什么是同步代码块(Synchronized Block) 同步代码块简单来说就是将一段代码用一把锁给锁起来, 只有获得了这把锁的线程才访问, 并且同一时刻, 只有一个线程能持有这把锁, 这样就保证了同 ...
- 6※、线程同步、同步锁、同步代码块的使用、同步锁释放的时机、ReentrantLock可重入锁、公平锁与非公平锁的区别、什么是死锁、线程间的通信(生产者和消费者模式)
线程锁 1.※线程的同步:(要确保对象锁是一致的) 1.未使用同步锁的抢票 2.使用了同步锁的抢票 3.线程-同步代码块的使用 4.同步方法和代码块的区别 5.同步锁释放的时机 练习:多线程生产手机 ...
- 从操作系统的PV操作理解JAVA的synchronized同步方法,同步代码块实现,及比较
也有利于理解操作系统的同步 知识果然是息息相关的 JAVA同样离不开操作系统的原理,不过他体现在虚拟机JVM中 synchronized关键字是同步关键字 首先我们知道在操作系统里 PV两者操作信息量 ...
- notify()唤醒线程,不会立即释放锁对象,需要等到当前同步代码块都执行完后才能释放锁对象
notify()唤醒线程,不会立即释放锁对象,需要等到当前同步代码块都执行完后才能释放锁对象 public class Test3 {public static void main(String[] ...
最新文章
- php减少损耗的方法之一 缓存对象
- 2021高考成绩查询大连,2021年大连高考各高中成绩及本科升学率数据排名及分析...
- UML总结---UML九种图关系说明
- java 判断object类型_Java多态的6大特性|乐字节
- 千万数据去重_如何在 1 秒内做到大数据精准去重?
- 由ViewStateException: The client disconnected想到的
- Patternodes 3 for Mac(创建图形矢量模式工具)
- 20.合并两个有序链表
- 笔记本计算机显示图标,笔记本电脑声音图标不见了?电脑声音图标显示红叉
- VS2015安装教程(带图解+下载地址+超详细)
- vue3 使用sass/scss
- 软件工程专业就业方向
- 物料-贴片电容-标签识别
- 计算机型号win7,教你win7系统电脑内存条型号怎么看
- 记录一次上网正常但是【登录客户端应用网络异常问题】
- 区块链技术与应用-BTC
- 图片轮播器——javascript
- 视觉slam14讲学习(一)之se3上的定位表示:轨迹显示与轨迹误差
- 前端的Vue相关的项目经验
- 前端:给中国奥运金牌数做可视化