JAVA Synchronized (二)
一,介绍
本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点。
所谓对象锁,就是就是synchronized 给某个对象 加锁。关于 对象锁 可参考:这篇文章
二,分析
synchronized可以修饰实例方法,如下形式:
1 public class MyObject {
2
3     synchronized public void methodA() {
4         //do something....
5     }
这里,synchronized 关键字锁住的是当前对象。这也是称为对象锁的原因。
为啥锁住当前对象?因为 methodA()是个实例方法,要想执行methodA(),需要以 对象.方法() 的形式进行调用(obj.methodA(),obj是MyObject类的一个对象,synchronized就是把obj这个对象加锁了)。
上面代码也可写成这样:

1 public class MyObject {
2
3     public void methodA() {
4         synchronized(this){
5             //do something....
6         }
7     }

三,特点
使用synchronized关键字同步一个明显的特点是:MyObject类中定义有多个synchronized修饰的实例方法时,若多个线程拥有同一个MyObject类的对象,则这些方法只能以同步的方式执行。即,执行完一个synchronized修饰的方法后,才能执行另一个synchronized修饰的方法。
如下:

 1 public class MyObject {
 2
 3     synchronized public void methodA() {
 4         //do something....
 5     }
 6
 7     synchronized public void methodB() {
 8         //do some other thing
 9     }
10 }

MyObject类中有两个synchronized修饰的方法。

 1 public class ThreadA extends Thread {
 2
 3     private MyObject object;
 4 //省略构造方法
 5     @Override
 6     public void run() {
 7         super.run();
 8         object.methodA();
 9     }
10 }

线程A执行methodA()

public class ThreadB extends Thread {
    private MyObject object;
//省略构造方法
    @Override
    public void run() {
        super.run();
        object.methodB();
    }
}

线程B执行methodB()

public class Run {
    public static void main(String[] args) {
        MyObject object = new MyObject();
        //线程A与线程B 持有的是同一个对象:object
        ThreadA a = new ThreadA(object);
        ThreadB b = new ThreadB(object);
        a.start();
        b.start();
    }
}

由于线程A和线程B持有同一个MyObject类的对象object,尽管这两个线程需要调用不同的方法,但是必须是同步的,比如:线程B需要等待线程A执行完了methodA()方法之后,它才能执行methodB()方法。
四,结论
从上可以看出,本文中讲述的 synchronized 锁的范围是整个对象。如果一个类中有多个synchronized修饰的同步方法,且多个线程持有该类的同一个对象(该类的相同的对象),尽管它们调用不同的方法,各个方法的执行也是同步的。
如果各个同步的方法之间没有共享变量,或者说各个方法之间没有联系,但也只能同步执行,这会影响效率。
五,应用--使用synchronized避免 因数据不一致性而导致读脏数据的情况
如下示例:

 1 public class MyObject {
 2
 3     private String userName = "b";
 4     private String passWord = "bb";
 5
 6     synchronized public void methodA(String userName, String passWord) {
 7         this.userName = userName;
 8         try{
 9             Thread.sleep(5000);
10         }catch(InterruptedException e){
11
12         }
13         this.passWord = passWord;
14     }
15
16     synchronized public void methodB() {
17         System.out.println("userName" + userName + ": " + "passWord" + passWord);
18     }
19 }

methodA()负责更改用户名和密码。在现实中,一个用户名对应着一个密码。。。
methodB()负责读取用户名和密码。
如果methodB()没有用synchronized 修饰,线程A在调用methodA()执行到第7行,更改了用户名,因某种原因(比如在第9行睡眠了)放弃了CPU。
此时,如果线程B去执行methodB(),那么读取到的用户名是线程A更改了的用户名("a"),但是密码却是原来的密码("bb")。因为,线程A睡眠了,还没有来得及更改密码。
但是,如果methodB()用synchronized修饰,那么线程B只能等待线程A执行完毕之后(即改了用户名,也改了密码),才能执行methodB读取用户名和密码。因此,就避免了数据的不一致性而导致的脏读问题。
JAVA Synchronized (二)的更多相关文章
- java synchronized使用
		java synchronized 基本上,所有并发的模式在解决线程冲突问题的时候,都是采用序列化共享资源的方案.这意味着在给定时刻只允许一个任务访问该资源.这个一般通过在代码上加一条锁语句实现,因为 ... 
- Java synchronized 详解
		Java synchronized 详解 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 1.当两个并发线程访问同一个对象object ... 
- Java EE : 二、图解 Cookie(小甜饼)
		目录 Java EE : 一.图解Http协议 Java EE : 二.图解 Cookie(小甜饼) Java EE : 三.图解Session(会话) 概述 一.概述 二.详细介绍Cookie 传输 ... 
- 利用JAVA生成二维码
		本文章整理于慕课网的学习视频<JAVA生成二维码>,如果想看视频内容请移步慕课网. 维基百科上对于二维码的解释. 二维条码是指在一维条码的基础上扩展出另一维具有可读性的条码,使用黑白矩形图 ... 
- Java Synchronized Blocks
		From http://tutorials.jenkov.com/java-concurrency/synchronized.html By Jakob Jenkov A Java synchro ... 
- java synchronized(一)
		java synchronized主要用于控制线程同步,中间有很多小的细节,知识,这里我简单的整理一下,做个记录.主要用于方法和代码块的控制 先说说方法控制 模拟银行存款和取款,创建一个Account ... 
- java实现二维码
		说起二维码,微信好像最先启用,随后各类二维码就开始流行起来了.那什么是二维码呢. 1.什么是二维码?百度一下即可 http://baike.baidu.com/view/132241.htm?fr=a ... 
- Java 设计模式(二)-六大原则
		Java 设计模式(二)-六大原则 单一职责原则(Single Responsibility Principle) 定义: 不要存在多余一个原因导致类变更,既一个类只负责一项职责. 问题由来: 当类A ... 
- Java进阶(二十五)Java连接mysql数据库(底层实现)
		Java进阶(二十五)Java连接mysql数据库(底层实现) 前言 很长时间没有系统的使用java做项目了.现在需要使用java完成一个实验,其中涉及到java连接数据库.让自己来写,记忆中已无从搜 ... 
- 20175212童皓桢 Java实验二-面向对象程序设计实验报告
		20175212童皓桢 Java实验二-面向对象程序设计实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 了解设 ... 
随机推荐
- spring boot 添加mybatis,以及相关配置
			首先在pom.xml文件里加入 <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifa ... 
- 转  vs2010转vs2008 其他的一样
			如果你使用VS2010的任何版本写代码,那么在VS2008中就不能打开VS2010的解决方案了,为此,通过以下三步就可以解决了一.对于工程名.sln; 1.用你喜欢的编辑器打开sln文件,比如note ... 
- Mac--安装kubernetes并运行echoserver
			安装minikube curl -Lo minikube https://storage.googleapis.com/minikube/releases/v0.15.0/minikube-darwi ... 
- MySQL的字符编码体系(一)——数据存储编码
			安装MySQL好多次了,每次都会纠结于数据库的字符编码配置,所以我决定这一次彻底把它理清. MySQL的字符编码结构比較细,它慷慨向分为两个部分:数据存储编码和传输数据编码.本篇讨论数据存储编码部分, ... 
- Android Studio——gradle同步出错:MALFORMED
			Android Studio之前使用本地的gradle-2.10,而后创建新的工程总是报错,信息如下: Gradle sync failed: MALFORMED 而后在File->Projec ... 
- HDU-1076-An Easy Task(Debian下水题測试.....)
			An Easy Task Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Tot ... 
- 【转载】5种网络IO模型
			同步(synchronous) IO和异步(asynchronous) IO,阻塞(blocking) IO和非阻塞(non-blocking)IO分别是什么,到底有什么区别?这个问题其实不同的人给出 ... 
- tomcat 实现域名crm.test.com訪问
			**tomcat 上下文.实现的效果.是在浏览器输入ip或者域名能直接訪问.不用输入项目project名字 正常初始化都是http://10.243.12.34:8080/plcrm.要变成 crm. ... 
- Intel Naming Strategy--2
			http://en.wikipedia.org/wiki/Intel_Corporation#Naming_strategy Naming strategy[edit] In 2006, Intel ... 
- 使用JXL对EXCLE的导入导出
			import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Da ... 
