Synchronized 互斥块(对象锁) 一个对象和一个monitor 的关系
来源:互联网 发布:mac看照片怎么下一张 编辑:程序博客网 时间:2024/06/14 14:08
Synchronized :锁住的是对象,出现synchronized表示随后的代码块要用到共享数据了,要锁住了。
一、3种形式。
1、synchronized(obj):可以任意指定对象.
2、synchronized(this):当前对象:当一个类加到内存时,常量池有一个地址直接指向当前正在执行的对象.
3、public synchronized void run():当前对象(this),这是实例方法,每一方法里存着一个This.方法
对象:可以是普通类 public class Test {}, 也可以是干活线程类 ,只要是new 类名 的所有对象。
**所以synchronized(this){} 和synchronized 方法差不多,反正是锁当前对象。
二、对于锁类其实也一样,因为一个类入内存后,还是java.lang.Class 的类对象。所以还是锁对象。
三、锁的数据:一个类成员数据:对象实例变量,类变量
1、object instance variables:对象实例变量,存在堆中。
2、class variables:类变量,存在method area。
如果您正在写一个变量,这个变量有可能随后被另一个线程读,
或您正在读一个变量,这个变量有可能随后被另一个线程写,
这时你必须用到变量的地方放一个synchronized,
四、例子
1、简单需求
例如:银行个人账户(对象):卡号,余额
如果一个小店主,顾客很多,如果都用微信付款的话,有可能同一时刻访问店主的银行个人账户的问题。
当一个顾客对店主的账号余额进行加减时,锁住账号,退出后,另一个顾客才能继续付钱,
顾客是看不见这些过程,只管提交就行,银行应该是相应的服务软件接收用户的请求。
2、代码说明
1>有4个线程,main()主线程,3个顾客子线程
因为是几个顾客有可能同时付款,所以需要线程。
2>一个店主银行个人账户的对象(对象里面有共享资源,余额)
银行个人账户的对象(peraccount)对应一个monitor。
3>执行步骤(只取其中一个结果分析)
第一:main线程执行到threads[0].start(),threads[1].start(),threads[2].start();
即3个线程入就绪对象,这是main代码执行完,cpu空
第二:调度程序选择threads[0]进入cpu。
第三:
(一)当jvm行到synchronized peraccount 这一句时,表示peraccount 对象里面有共享数据,
去取一把钥匙,看人家是否已经锁住共享数据了.去哪里取呢?monitor大楼。
(二)这时cpu空,调度程序安排thread[2]入cpu,thread[0]去monitor大楼取钥匙去了
两个过程同时执行。
(三)当jvm 执行到threads[2]到synchronized peraccount 时,又该去peraccount monitor大楼取钥匙了。
同时cpu还是空。
(四)调度程序安排thread[1]入cpu执行,在monitor大厅等待,
同时cpu空,这时,thread[0]已经占用特殊房间,表示取得钥匙,获得一把锁,锁住后面的代码。
1》调度程序安排thread[0]进入Cpu,因为后面的代码已经被thread[0]锁住,所以一直占cpu执行完。
cpu空,同时特殊房间空,thread[1]和thread[2]竞争,thread[1]进入特殊房间,获得锁。
2》thread[1]占用特殊房间,表示取得钥匙,获得一把锁,锁住后面的代码。所以一直占cpu执行完,
cpu空,同时特殊房间空,thread[2]进入特殊房间。
3》thread[2]已经占用特殊房间,表示取得钥匙,获得一把锁,锁住后面的代码。所以一直占cpu执行完,cpu空
整个过程完
3、图形
4、代码
package concurrency;
/**
* 银行个人账户,共享数据,
* cardnumber,balance
* 一个卡号,多人可以对余额进行修改。
*
*/
class Account {
private String cardnumber;//卡号
private float balance; //余额
public Account(String cardnumber, float balance) {
this.cardnumber = cardnumber;
this.balance = balance;
}
// 存钱
public void deposit(float sum) {
balance= balance+sum;
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//得到当前钱数。
public float getBalance() {
return balance;
}
}
/**
* PayToAccount 现在是静态类
* 可以new 多个对象,表示多人用微信付款
* 每一支付的人和店主的个人账号相连
*/
public class PayToAccount implements Runnable {
private Account peraccount; //表示和店主个人账号对象相连接
private float sum;
public PayToAccount(Account peraccount,float sum) {
this.peraccount = peraccount;
this.sum=sum;
}
public void run() {
System.out.println(Thread.currentThread().getName()+" run()");
synchronized (peraccount) {//到这里表示要锁住店主的个人账号对象了,后面涉及对同一对象进行操作。
System.out.println(Thread.currentThread().getName()+" 取得钥匙");
peraccount.deposit(this.sum);
System.out.println(Thread.currentThread().getName() + ":"
+peraccount.getBalance());
}
}
/**客户微信软件---扫一下,哪么微信软件应该提取了店主的个人账号,点支付之后,应该是执行PayToAccount的run操作。
* 下面是模拟顾客扫微信的功能,只用了固定的3个顾客,但是现实顾客数无法确定。
*/
public static void main(String[] args) {
//店主墙上的微信号(也就是店主的银行个人账号)
Account account = new Account("yang", 50.0f);//
//相当客户扫一扫:把自己和店主的银行个人账号相连,
//账号,存的钱数。
PayToAccount buyer1 = new PayToAccount(account,50.0f);
PayToAccount buyer2 = new PayToAccount(account,125.0f);
PayToAccount buyer3 = new PayToAccount(account,310.0f);
/**
* 相当3个客户都点了支付按钮,付钱,
* 涉及同时对一个账号进行操作,
* 建立三个新的驱动线程带上三个新的干活线程(客户付款线程)
*在这个例子中,三个驱动线程是new Thread,
*干活线程是buyer1,buyer2,buyer3,锁住的对象是Account(共享资源)
*/
Thread threads[] = new Thread[3];
Thread threads[] = new Thread[3];
threads[0] = new Thread(buyer1, "第一个顾客" );
threads[1] = new Thread(buyer2, "第二个顾客" );
threads[2] = new Thread(buyer3, "第三个顾客" );
/**
/**
* 付钱,客户任务已经完成,就是等银行返回消息了。
*/
threads[0].start();
threads[1].start();
threads[2].start();
}
}
只是为了理解monitor,所以选择
其中的一个运行结果:
第一个顾客 取得钥匙
第一个顾客:100.0
第二个顾客 取得钥匙
第二个顾客:225
第三个顾客 取得钥匙
第三个顾客:535.0
- Synchronized 互斥块(对象锁) 一个对象和一个monitor 的关系
- 多线程之synchronized锁字符串对象的一个易错点
- 2.2.5一个对象不同的方法synchronized (this)是同一个对象锁
- java中线程同步Synchronized,监视器monitor和锁lock的关系是什
- 笔试:当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? ?(2nd)
- 当一个线程进入一个对象的一个synchronized( )方法后,其它线程是否可进入此对象的其它方法
- 当一个线程进入一个对象的一个synchronized方法后,其它线程是否可进入此对象的其它方法? ?(2nd)
- 直接定义一个对象和new一个对象的区别
- Synchronized(对象锁)和Static Synchronized(类锁)的区别
- Synchronized(对象锁)和Static Synchronized(类锁)的区别
- Synchronized(对象锁)和Static Synchronized(类锁)的区别
- Synchronized(对象锁)和Static Synchronized(类锁)的区别
- 深入理解Java中Synchronized(对象锁)和Static Synchronized(类锁)的区别
- 当一个线程进入一个对象的synchronized() 方法后,其他线程是否可以进入此对象的其他方法
- (实验)Java一个线程用synchronized嵌套锁多个对象时调用wait()只释放wait函数关联的所对象还是释放所有锁对象
- 创建一个类和相应的对象
- 一个对象的toString()
- C++ 中临时对象 和 const 对象 的一个区别
- Intellij main方法
- 输出
- HTML+CSS编写静态网站-01 课程简介
- thread04
- codevs 1214 线段覆盖
- Synchronized 互斥块(对象锁) 一个对象和一个monitor 的关系
- 第43课: Spark 1.6 RPC内幕解密:运行机制、源码详解、Netty与Akka等
- 好久不写了
- 如何快速下载DockerToolbox?使用国内开源镜像站点
- laravel中查询语句
- Centos7 安装SVN
- QFileDialog 的各种属性设置介绍
- Qt5.5 QFileDialog类的使用方法
- js 简单计算器