Day13_71_线程同步(synchronized)
2024-08-27 20:15:00
线程同步
* 异步编程模型和同步编程模拟的区别?
- 有T1和T2 两个线程
> 异步编程模型:T1线程执行T1的,T2线程执行T2的,谁也不等谁
> 同步编程模型:T1和T2 线程执行,当T1线程必须等T2线程执行结束后才能执行,这是同步编程模型
什么时候需要同步?
- 为了数据的安全 例如:同一银行卡同时取款
尽管降低了应用程序的效率,但是有时候为了保证数据是安全的必须加入同步机制.
线程同步机制使程序(等同)变成了单线程。
线程同步需要哪些条件?
- 必须是多线程环境
- 多线程环境共享同一个数据
- 共享的数据涉及到修改操作
使用线程同步机制,保护数据安全
使用 synchronized(共享对象) {
把需要同步的代码放到该同步语句块中
}
* synchronized 的原理?
> t1线程执行中遇到了synchronized 关键字,就回去找synchronized中的共享对象所持有的对象锁(每个对象都有对象锁有0和1两个值),如果找到了该对象的对象锁,则进入同步语句块中执行程序,当同步语句块中的
代码执行结束之后,t1线程会归还对象锁。
> 在t1线程执行同步语句块的过程中,如果t2线程也过来执行,也遇到了synchronized关键字,所以也会去找synchronized中共享对象的对象锁,但是此时该对象锁正在被t1使用,所提t2线程只能在此等候t1线程归还
对象锁之后才能拿到对象锁进入同步语句块执行代码。
- synchronized也**可以**加到成员方法上
public synchronized void withdrow(double money) {}
代码实例
//线程的同步异步
public class ThreadTest11 {
public static void main(String[] args) { //创建一个账户
Account account=new Account("608521478",5000); //创建线程
Processor_11 processor_11=new Processor_11(account); // 将同一个账户传进去 Thread thread1=new Thread(processor_11);
Thread thread2=new Thread(processor_11); //启动线程
thread1.start();
thread2.start(); } }
//线程类
class Processor_11 implements Runnable{
//创建成员变量 账户
Account act;
//构造方法
Processor_11(){}
Processor_11(Account act){
this.act=act;
}
// 重写run方法
@Override
public void run() {
act.withDraw(1000);
}
}
//银行 账户类
class Account{
//属性
private String actNo;
private double balance;
//构造方法
public Account(){}
public Account (String actNo,double balance){
this.actNo=actNo;
this.balance=balance;
}
//getter and setter方法
public String getActNo() {
return actNo;
}
public void setActNo(String actNo) {
this.actNo = actNo;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
//取款的方法
public void withDraw(double money){ //对当前账户进行取款操作
//把需要同步的代码,放到同步语句块中
synchronized (this){
//取款后的余额
double after=balance-money;
//更新余额
this.setBalance(after);
System.out.println("取款1000成功,余额为:"+this.getBalance()+"元");
}
}
}
最新文章
- java.lang.IllegalStateException: Web app root system property already set to different value
- 【转】sed 简明教程
- JS如何判断包括IE11在内的IE浏览器 <;转载>;
- 默认hosts后面为files dns
- Support Library官方教程(3)android studio中导入支援包
- 水平/竖直居中在旧版Safari上的bug
- cmd命名设置成全局
- 【27前端】背景半透明rgba LESS实践
- Linux内核-系统调用
- Galaxy (hdu 5073 数学)
- Java EE基础之JSP(二)
- 【OpenCV-Python:实现人脸、人眼、嘴巴识别】实战(一)
- 定时任务调度工作(学习记录 三)timer其他重要函数
- MyBatis:Pagehelper分页
- Microsoft DQS sqlException 0x80131904 - SetDataQualitySessionPhaseTwo
- [No0000B6]C#中 ==与equals的区别
- mail命令入门及进阶
- CTF竞赛(简介)
- redhat 6.6 安装 (LVM)
- [py][lc]python的纸牌知识点
热门文章
- 手把手教你Spring Boot整合Mybatis Plus和Swagger2
- yum安装MySQL8 - Centos8
- CentOS7安装Maven3.6.3及Git2.8.3
- Django3.0 + nginx + uwsgi 部署
- HDOJ-1160(最长上升子序列变形)
- C语言之三字棋的简单实现及扩展
- Spring中各种扩展原理及容器创建原理
- 两种常见Content-type的方便理解
- P3160 [CQOI2012]局部极小值 题解(状压DP+容斥)
- Lzzy高级语言程序设计之for循环